ActivityManagerService.java revision ca2af9e38c31c823f72a6060c45b27fc968e6bd8
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.text.format.DateUtils;
203import android.text.format.Time;
204import android.text.style.SuggestionSpan;
205import android.util.ArrayMap;
206import android.util.ArraySet;
207import android.util.AtomicFile;
208import android.util.DebugUtils;
209import android.util.EventLog;
210import android.util.Log;
211import android.util.Pair;
212import android.util.PrintWriterPrinter;
213import android.util.Slog;
214import android.util.SparseArray;
215import android.util.TimeUtils;
216import android.util.Xml;
217import android.view.Display;
218import android.view.Gravity;
219import android.view.LayoutInflater;
220import android.view.View;
221import android.view.WindowManager;
222
223import java.io.File;
224import java.io.FileDescriptor;
225import java.io.FileInputStream;
226import java.io.FileNotFoundException;
227import java.io.FileOutputStream;
228import java.io.IOException;
229import java.io.InputStreamReader;
230import java.io.PrintWriter;
231import java.io.StringWriter;
232import java.lang.ref.WeakReference;
233import java.nio.charset.StandardCharsets;
234import java.util.ArrayList;
235import java.util.Arrays;
236import java.util.Collections;
237import java.util.Comparator;
238import java.util.HashMap;
239import java.util.HashSet;
240import java.util.Iterator;
241import java.util.List;
242import java.util.Locale;
243import java.util.Map;
244import java.util.Objects;
245import java.util.Set;
246import java.util.concurrent.atomic.AtomicBoolean;
247import java.util.concurrent.atomic.AtomicLong;
248
249import dalvik.system.VMRuntime;
250
251import libcore.io.IoUtils;
252import libcore.util.EmptyArray;
253
254import static android.Manifest.permission.INTERACT_ACROSS_USERS;
255import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
256import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
257import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
258import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
259import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
260import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
261import static android.app.ActivityManager.StackId.FIRST_STATIC_STACK_ID;
262import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
263import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
264import static android.app.ActivityManager.StackId.HOME_STACK_ID;
265import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
266import static android.app.ActivityManager.StackId.LAST_STATIC_STACK_ID;
267import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
268import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
269import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
270import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
271import static android.content.pm.PackageManager.GET_PROVIDERS;
272import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
273import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_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    boolean mSupportsLeanbackOnly;
1349    Rect mDefaultPinnedStackBounds;
1350    IActivityController mController = null;
1351    boolean mControllerIsAMonkey = false;
1352    String mProfileApp = null;
1353    ProcessRecord mProfileProc = null;
1354    String mProfileFile;
1355    ParcelFileDescriptor mProfileFd;
1356    int mSamplingInterval = 0;
1357    boolean mAutoStopProfiler = false;
1358    int mProfileType = 0;
1359    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1360    String mMemWatchDumpProcName;
1361    String mMemWatchDumpFile;
1362    int mMemWatchDumpPid;
1363    int mMemWatchDumpUid;
1364    String mTrackAllocationApp = null;
1365    String mNativeDebuggingApp = null;
1366
1367    final long[] mTmpLong = new long[2];
1368
1369    static final class ProcessChangeItem {
1370        static final int CHANGE_ACTIVITIES = 1<<0;
1371        static final int CHANGE_PROCESS_STATE = 1<<1;
1372        int changes;
1373        int uid;
1374        int pid;
1375        int processState;
1376        boolean foregroundActivities;
1377    }
1378
1379    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1380    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1381
1382    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1383    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1384
1385    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1386    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1387
1388    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1389    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1390
1391    /**
1392     * Runtime CPU use collection thread.  This object's lock is used to
1393     * perform synchronization with the thread (notifying it to run).
1394     */
1395    final Thread mProcessCpuThread;
1396
1397    /**
1398     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1399     * Must acquire this object's lock when accessing it.
1400     * NOTE: this lock will be held while doing long operations (trawling
1401     * through all processes in /proc), so it should never be acquired by
1402     * any critical paths such as when holding the main activity manager lock.
1403     */
1404    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1405            MONITOR_THREAD_CPU_USAGE);
1406    final AtomicLong mLastCpuTime = new AtomicLong(0);
1407    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1408
1409    long mLastWriteTime = 0;
1410
1411    /**
1412     * Used to retain an update lock when the foreground activity is in
1413     * immersive mode.
1414     */
1415    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1416
1417    /**
1418     * Set to true after the system has finished booting.
1419     */
1420    boolean mBooted = false;
1421
1422    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1423    int mProcessLimitOverride = -1;
1424
1425    WindowManagerService mWindowManager;
1426    final ActivityThread mSystemThread;
1427
1428    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1429        final ProcessRecord mApp;
1430        final int mPid;
1431        final IApplicationThread mAppThread;
1432
1433        AppDeathRecipient(ProcessRecord app, int pid,
1434                IApplicationThread thread) {
1435            if (DEBUG_ALL) Slog.v(
1436                TAG, "New death recipient " + this
1437                + " for thread " + thread.asBinder());
1438            mApp = app;
1439            mPid = pid;
1440            mAppThread = thread;
1441        }
1442
1443        @Override
1444        public void binderDied() {
1445            if (DEBUG_ALL) Slog.v(
1446                TAG, "Death received in " + this
1447                + " for thread " + mAppThread.asBinder());
1448            synchronized(ActivityManagerService.this) {
1449                appDiedLocked(mApp, mPid, mAppThread, true);
1450            }
1451        }
1452    }
1453
1454    static final int SHOW_ERROR_UI_MSG = 1;
1455    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1456    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1457    static final int UPDATE_CONFIGURATION_MSG = 4;
1458    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1459    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1460    static final int SERVICE_TIMEOUT_MSG = 12;
1461    static final int UPDATE_TIME_ZONE = 13;
1462    static final int SHOW_UID_ERROR_UI_MSG = 14;
1463    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1464    static final int PROC_START_TIMEOUT_MSG = 20;
1465    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1466    static final int KILL_APPLICATION_MSG = 22;
1467    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1468    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1469    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1470    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1471    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1472    static final int CLEAR_DNS_CACHE_MSG = 28;
1473    static final int UPDATE_HTTP_PROXY_MSG = 29;
1474    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1475    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1476    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1477    static final int REPORT_MEM_USAGE_MSG = 33;
1478    static final int REPORT_USER_SWITCH_MSG = 34;
1479    static final int CONTINUE_USER_SWITCH_MSG = 35;
1480    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1481    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1482    static final int PERSIST_URI_GRANTS_MSG = 38;
1483    static final int REQUEST_ALL_PSS_MSG = 39;
1484    static final int START_PROFILES_MSG = 40;
1485    static final int UPDATE_TIME = 41;
1486    static final int SYSTEM_USER_START_MSG = 42;
1487    static final int SYSTEM_USER_CURRENT_MSG = 43;
1488    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1489    static final int FINISH_BOOTING_MSG = 45;
1490    static final int START_USER_SWITCH_UI_MSG = 46;
1491    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1492    static final int DISMISS_DIALOG_UI_MSG = 48;
1493    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1494    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1495    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1496    static final int DELETE_DUMPHEAP_MSG = 52;
1497    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1498    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1499    static final int REPORT_TIME_TRACKER_MSG = 55;
1500    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1501    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1502    static final int APP_BOOST_DEACTIVATE_MSG = 58;
1503    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1504    static final int IDLE_UIDS_MSG = 60;
1505    static final int SYSTEM_USER_UNLOCK_MSG = 61;
1506    static final int LOG_STACK_STATE = 62;
1507    static final int VR_MODE_CHANGE_MSG = 63;
1508    static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1509    static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1510    static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1511    static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
1512    static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
1513    static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
1514
1515    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1516    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1517    static final int FIRST_COMPAT_MODE_MSG = 300;
1518    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1519
1520    static ServiceThread sKillThread = null;
1521    static KillHandler sKillHandler = null;
1522
1523    CompatModeDialog mCompatModeDialog;
1524    long mLastMemUsageReportTime = 0;
1525
1526    /**
1527     * Flag whether the current user is a "monkey", i.e. whether
1528     * the UI is driven by a UI automation tool.
1529     */
1530    private boolean mUserIsMonkey;
1531
1532    /** Flag whether the device has a Recents UI */
1533    boolean mHasRecents;
1534
1535    /** The dimensions of the thumbnails in the Recents UI. */
1536    int mThumbnailWidth;
1537    int mThumbnailHeight;
1538    float mFullscreenThumbnailScale;
1539
1540    final ServiceThread mHandlerThread;
1541    final MainHandler mHandler;
1542    final UiHandler mUiHandler;
1543
1544    PackageManagerInternal mPackageManagerInt;
1545
1546    // VoiceInteraction session ID that changes for each new request except when
1547    // being called for multiwindow assist in a single session.
1548    private int mViSessionId = 1000;
1549
1550    final class KillHandler extends Handler {
1551        static final int KILL_PROCESS_GROUP_MSG = 4000;
1552
1553        public KillHandler(Looper looper) {
1554            super(looper, null, true);
1555        }
1556
1557        @Override
1558        public void handleMessage(Message msg) {
1559            switch (msg.what) {
1560                case KILL_PROCESS_GROUP_MSG:
1561                {
1562                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1563                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1564                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1565                }
1566                break;
1567
1568                default:
1569                    super.handleMessage(msg);
1570            }
1571        }
1572    }
1573
1574    final class UiHandler extends Handler {
1575        public UiHandler() {
1576            super(com.android.server.UiThread.get().getLooper(), null, true);
1577        }
1578
1579        @Override
1580        public void handleMessage(Message msg) {
1581            switch (msg.what) {
1582            case SHOW_ERROR_UI_MSG: {
1583                mAppErrors.handleShowAppErrorUi(msg);
1584                ensureBootCompleted();
1585            } break;
1586            case SHOW_NOT_RESPONDING_UI_MSG: {
1587                mAppErrors.handleShowAnrUi(msg);
1588                ensureBootCompleted();
1589            } break;
1590            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1591                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1592                synchronized (ActivityManagerService.this) {
1593                    ProcessRecord proc = (ProcessRecord) data.get("app");
1594                    if (proc == null) {
1595                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1596                        break;
1597                    }
1598                    if (proc.crashDialog != null) {
1599                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1600                        return;
1601                    }
1602                    AppErrorResult res = (AppErrorResult) data.get("result");
1603                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1604                        Dialog d = new StrictModeViolationDialog(mContext,
1605                                ActivityManagerService.this, res, proc);
1606                        d.show();
1607                        proc.crashDialog = d;
1608                    } else {
1609                        // The device is asleep, so just pretend that the user
1610                        // saw a crash dialog and hit "force quit".
1611                        res.set(0);
1612                    }
1613                }
1614                ensureBootCompleted();
1615            } break;
1616            case SHOW_FACTORY_ERROR_UI_MSG: {
1617                Dialog d = new FactoryErrorDialog(
1618                    mContext, msg.getData().getCharSequence("msg"));
1619                d.show();
1620                ensureBootCompleted();
1621            } break;
1622            case WAIT_FOR_DEBUGGER_UI_MSG: {
1623                synchronized (ActivityManagerService.this) {
1624                    ProcessRecord app = (ProcessRecord)msg.obj;
1625                    if (msg.arg1 != 0) {
1626                        if (!app.waitedForDebugger) {
1627                            Dialog d = new AppWaitingForDebuggerDialog(
1628                                    ActivityManagerService.this,
1629                                    mContext, app);
1630                            app.waitDialog = d;
1631                            app.waitedForDebugger = true;
1632                            d.show();
1633                        }
1634                    } else {
1635                        if (app.waitDialog != null) {
1636                            app.waitDialog.dismiss();
1637                            app.waitDialog = null;
1638                        }
1639                    }
1640                }
1641            } break;
1642            case SHOW_UID_ERROR_UI_MSG: {
1643                if (mShowDialogs) {
1644                    AlertDialog d = new BaseErrorDialog(mContext);
1645                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1646                    d.setCancelable(false);
1647                    d.setTitle(mContext.getText(R.string.android_system_label));
1648                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1649                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1650                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1651                    d.show();
1652                }
1653            } break;
1654            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1655                if (mShowDialogs) {
1656                    AlertDialog d = new BaseErrorDialog(mContext);
1657                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1658                    d.setCancelable(false);
1659                    d.setTitle(mContext.getText(R.string.android_system_label));
1660                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1661                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1662                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1663                    d.show();
1664                }
1665            } break;
1666            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1667                synchronized (ActivityManagerService.this) {
1668                    ActivityRecord ar = (ActivityRecord) msg.obj;
1669                    if (mCompatModeDialog != null) {
1670                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1671                                ar.info.applicationInfo.packageName)) {
1672                            return;
1673                        }
1674                        mCompatModeDialog.dismiss();
1675                        mCompatModeDialog = null;
1676                    }
1677                    if (ar != null && false) {
1678                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1679                                ar.packageName)) {
1680                            int mode = mCompatModePackages.computeCompatModeLocked(
1681                                    ar.info.applicationInfo);
1682                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1683                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1684                                mCompatModeDialog = new CompatModeDialog(
1685                                        ActivityManagerService.this, mContext,
1686                                        ar.info.applicationInfo);
1687                                mCompatModeDialog.show();
1688                            }
1689                        }
1690                    }
1691                }
1692                break;
1693            }
1694            case START_USER_SWITCH_UI_MSG: {
1695                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1696                break;
1697            }
1698            case DISMISS_DIALOG_UI_MSG: {
1699                final Dialog d = (Dialog) msg.obj;
1700                d.dismiss();
1701                break;
1702            }
1703            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1704                dispatchProcessesChanged();
1705                break;
1706            }
1707            case DISPATCH_PROCESS_DIED_UI_MSG: {
1708                final int pid = msg.arg1;
1709                final int uid = msg.arg2;
1710                dispatchProcessDied(pid, uid);
1711                break;
1712            }
1713            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1714                dispatchUidsChanged();
1715            } break;
1716            }
1717        }
1718    }
1719
1720    final class MainHandler extends Handler {
1721        public MainHandler(Looper looper) {
1722            super(looper, null, true);
1723        }
1724
1725        @Override
1726        public void handleMessage(Message msg) {
1727            switch (msg.what) {
1728            case UPDATE_CONFIGURATION_MSG: {
1729                final ContentResolver resolver = mContext.getContentResolver();
1730                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1731                        msg.arg1);
1732            } break;
1733            case GC_BACKGROUND_PROCESSES_MSG: {
1734                synchronized (ActivityManagerService.this) {
1735                    performAppGcsIfAppropriateLocked();
1736                }
1737            } break;
1738            case SERVICE_TIMEOUT_MSG: {
1739                if (mDidDexOpt) {
1740                    mDidDexOpt = false;
1741                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1742                    nmsg.obj = msg.obj;
1743                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1744                    return;
1745                }
1746                mServices.serviceTimeout((ProcessRecord)msg.obj);
1747            } break;
1748            case UPDATE_TIME_ZONE: {
1749                synchronized (ActivityManagerService.this) {
1750                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1751                        ProcessRecord r = mLruProcesses.get(i);
1752                        if (r.thread != null) {
1753                            try {
1754                                r.thread.updateTimeZone();
1755                            } catch (RemoteException ex) {
1756                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1757                            }
1758                        }
1759                    }
1760                }
1761            } break;
1762            case CLEAR_DNS_CACHE_MSG: {
1763                synchronized (ActivityManagerService.this) {
1764                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1765                        ProcessRecord r = mLruProcesses.get(i);
1766                        if (r.thread != null) {
1767                            try {
1768                                r.thread.clearDnsCache();
1769                            } catch (RemoteException ex) {
1770                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1771                            }
1772                        }
1773                    }
1774                }
1775            } break;
1776            case UPDATE_HTTP_PROXY_MSG: {
1777                ProxyInfo proxy = (ProxyInfo)msg.obj;
1778                String host = "";
1779                String port = "";
1780                String exclList = "";
1781                Uri pacFileUrl = Uri.EMPTY;
1782                if (proxy != null) {
1783                    host = proxy.getHost();
1784                    port = Integer.toString(proxy.getPort());
1785                    exclList = proxy.getExclusionListAsString();
1786                    pacFileUrl = proxy.getPacFileUrl();
1787                }
1788                synchronized (ActivityManagerService.this) {
1789                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1790                        ProcessRecord r = mLruProcesses.get(i);
1791                        if (r.thread != null) {
1792                            try {
1793                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1794                            } catch (RemoteException ex) {
1795                                Slog.w(TAG, "Failed to update http proxy for: " +
1796                                        r.info.processName);
1797                            }
1798                        }
1799                    }
1800                }
1801            } break;
1802            case PROC_START_TIMEOUT_MSG: {
1803                if (mDidDexOpt) {
1804                    mDidDexOpt = false;
1805                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1806                    nmsg.obj = msg.obj;
1807                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1808                    return;
1809                }
1810                ProcessRecord app = (ProcessRecord)msg.obj;
1811                synchronized (ActivityManagerService.this) {
1812                    processStartTimedOutLocked(app);
1813                }
1814            } break;
1815            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1816                ProcessRecord app = (ProcessRecord)msg.obj;
1817                synchronized (ActivityManagerService.this) {
1818                    processContentProviderPublishTimedOutLocked(app);
1819                }
1820            } break;
1821            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1822                synchronized (ActivityManagerService.this) {
1823                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1824                }
1825            } break;
1826            case KILL_APPLICATION_MSG: {
1827                synchronized (ActivityManagerService.this) {
1828                    int appid = msg.arg1;
1829                    boolean restart = (msg.arg2 == 1);
1830                    Bundle bundle = (Bundle)msg.obj;
1831                    String pkg = bundle.getString("pkg");
1832                    String reason = bundle.getString("reason");
1833                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1834                            false, UserHandle.USER_ALL, reason);
1835                }
1836            } break;
1837            case FINALIZE_PENDING_INTENT_MSG: {
1838                ((PendingIntentRecord)msg.obj).completeFinalize();
1839            } break;
1840            case POST_HEAVY_NOTIFICATION_MSG: {
1841                INotificationManager inm = NotificationManager.getService();
1842                if (inm == null) {
1843                    return;
1844                }
1845
1846                ActivityRecord root = (ActivityRecord)msg.obj;
1847                ProcessRecord process = root.app;
1848                if (process == null) {
1849                    return;
1850                }
1851
1852                try {
1853                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1854                    String text = mContext.getString(R.string.heavy_weight_notification,
1855                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1856                    Notification notification = new Notification.Builder(context)
1857                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1858                            .setWhen(0)
1859                            .setOngoing(true)
1860                            .setTicker(text)
1861                            .setColor(mContext.getColor(
1862                                    com.android.internal.R.color.system_notification_accent_color))
1863                            .setContentTitle(text)
1864                            .setContentText(
1865                                    mContext.getText(R.string.heavy_weight_notification_detail))
1866                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1867                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1868                                    new UserHandle(root.userId)))
1869                            .build();
1870                    try {
1871                        int[] outId = new int[1];
1872                        inm.enqueueNotificationWithTag("android", "android", null,
1873                                R.string.heavy_weight_notification,
1874                                notification, outId, root.userId);
1875                    } catch (RuntimeException e) {
1876                        Slog.w(ActivityManagerService.TAG,
1877                                "Error showing notification for heavy-weight app", e);
1878                    } catch (RemoteException e) {
1879                    }
1880                } catch (NameNotFoundException e) {
1881                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1882                }
1883            } break;
1884            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1885                INotificationManager inm = NotificationManager.getService();
1886                if (inm == null) {
1887                    return;
1888                }
1889                try {
1890                    inm.cancelNotificationWithTag("android", null,
1891                            R.string.heavy_weight_notification,  msg.arg1);
1892                } catch (RuntimeException e) {
1893                    Slog.w(ActivityManagerService.TAG,
1894                            "Error canceling notification for service", e);
1895                } catch (RemoteException e) {
1896                }
1897            } break;
1898            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1899                synchronized (ActivityManagerService.this) {
1900                    checkExcessivePowerUsageLocked(true);
1901                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1902                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1903                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1904                }
1905            } break;
1906            case REPORT_MEM_USAGE_MSG: {
1907                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1908                Thread thread = new Thread() {
1909                    @Override public void run() {
1910                        reportMemUsage(memInfos);
1911                    }
1912                };
1913                thread.start();
1914                break;
1915            }
1916            case REPORT_USER_SWITCH_MSG: {
1917                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1918                break;
1919            }
1920            case CONTINUE_USER_SWITCH_MSG: {
1921                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1922                break;
1923            }
1924            case USER_SWITCH_TIMEOUT_MSG: {
1925                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1926                break;
1927            }
1928            case IMMERSIVE_MODE_LOCK_MSG: {
1929                final boolean nextState = (msg.arg1 != 0);
1930                if (mUpdateLock.isHeld() != nextState) {
1931                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1932                            "Applying new update lock state '" + nextState
1933                            + "' for " + (ActivityRecord)msg.obj);
1934                    if (nextState) {
1935                        mUpdateLock.acquire();
1936                    } else {
1937                        mUpdateLock.release();
1938                    }
1939                }
1940                break;
1941            }
1942            case PERSIST_URI_GRANTS_MSG: {
1943                writeGrantedUriPermissions();
1944                break;
1945            }
1946            case REQUEST_ALL_PSS_MSG: {
1947                synchronized (ActivityManagerService.this) {
1948                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1949                }
1950                break;
1951            }
1952            case START_PROFILES_MSG: {
1953                synchronized (ActivityManagerService.this) {
1954                    mUserController.startProfilesLocked();
1955                }
1956                break;
1957            }
1958            case UPDATE_TIME: {
1959                synchronized (ActivityManagerService.this) {
1960                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1961                        ProcessRecord r = mLruProcesses.get(i);
1962                        if (r.thread != null) {
1963                            try {
1964                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1965                            } catch (RemoteException ex) {
1966                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1967                            }
1968                        }
1969                    }
1970                }
1971                break;
1972            }
1973            case SYSTEM_USER_START_MSG: {
1974                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1975                        Integer.toString(msg.arg1), msg.arg1);
1976                mSystemServiceManager.startUser(msg.arg1);
1977                break;
1978            }
1979            case SYSTEM_USER_UNLOCK_MSG: {
1980                final int userId = msg.arg1;
1981                mSystemServiceManager.unlockUser(userId);
1982                synchronized (ActivityManagerService.this) {
1983                    mRecentTasks.loadUserRecentsLocked(userId);
1984                }
1985                if (userId == UserHandle.USER_SYSTEM) {
1986                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
1987                }
1988                installEncryptionUnawareProviders(userId);
1989                mUserController.finishUserUnlocked((UserState) msg.obj);
1990                break;
1991            }
1992            case SYSTEM_USER_CURRENT_MSG: {
1993                mBatteryStatsService.noteEvent(
1994                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1995                        Integer.toString(msg.arg2), msg.arg2);
1996                mBatteryStatsService.noteEvent(
1997                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1998                        Integer.toString(msg.arg1), msg.arg1);
1999                mSystemServiceManager.switchUser(msg.arg1);
2000                break;
2001            }
2002            case ENTER_ANIMATION_COMPLETE_MSG: {
2003                synchronized (ActivityManagerService.this) {
2004                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2005                    if (r != null && r.app != null && r.app.thread != null) {
2006                        try {
2007                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2008                        } catch (RemoteException e) {
2009                        }
2010                    }
2011                }
2012                break;
2013            }
2014            case FINISH_BOOTING_MSG: {
2015                if (msg.arg1 != 0) {
2016                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2017                    finishBooting();
2018                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2019                }
2020                if (msg.arg2 != 0) {
2021                    enableScreenAfterBoot();
2022                }
2023                break;
2024            }
2025            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2026                try {
2027                    Locale l = (Locale) msg.obj;
2028                    IBinder service = ServiceManager.getService("mount");
2029                    IMountService mountService = IMountService.Stub.asInterface(service);
2030                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2031                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2032                } catch (RemoteException e) {
2033                    Log.e(TAG, "Error storing locale for decryption UI", e);
2034                }
2035                break;
2036            }
2037            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
2038                synchronized (ActivityManagerService.this) {
2039                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2040                        try {
2041                            // Make a one-way callback to the listener
2042                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
2043                        } catch (RemoteException e){
2044                            // Handled by the RemoteCallbackList
2045                        }
2046                    }
2047                    mTaskStackListeners.finishBroadcast();
2048                }
2049                break;
2050            }
2051            case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
2052                synchronized (ActivityManagerService.this) {
2053                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2054                        try {
2055                            // Make a one-way callback to the listener
2056                            mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
2057                        } catch (RemoteException e){
2058                            // Handled by the RemoteCallbackList
2059                        }
2060                    }
2061                    mTaskStackListeners.finishBroadcast();
2062                }
2063                break;
2064            }
2065            case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
2066                synchronized (ActivityManagerService.this) {
2067                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2068                        try {
2069                            // Make a one-way callback to the listener
2070                            mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
2071                        } catch (RemoteException e){
2072                            // Handled by the RemoteCallbackList
2073                        }
2074                    }
2075                    mTaskStackListeners.finishBroadcast();
2076                }
2077                break;
2078            }
2079            case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2080                synchronized (ActivityManagerService.this) {
2081                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2082                        try {
2083                            // Make a one-way callback to the listener
2084                            mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2085                        } catch (RemoteException e){
2086                            // Handled by the RemoteCallbackList
2087                        }
2088                    }
2089                    mTaskStackListeners.finishBroadcast();
2090                }
2091                break;
2092            }
2093            case NOTIFY_FORCED_RESIZABLE_MSG: {
2094                synchronized (ActivityManagerService.this) {
2095                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2096                        try {
2097                            // Make a one-way callback to the listener
2098                            mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
2099                                    (String) msg.obj, msg.arg1);
2100                        } catch (RemoteException e){
2101                            // Handled by the RemoteCallbackList
2102                        }
2103                    }
2104                    mTaskStackListeners.finishBroadcast();
2105                }
2106                break;
2107            }
2108                case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
2109                    synchronized (ActivityManagerService.this) {
2110                        for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2111                            try {
2112                                // Make a one-way callback to the listener
2113                                mTaskStackListeners.getBroadcastItem(i)
2114                                        .onActivityDismissingDockedStack();
2115                            } catch (RemoteException e){
2116                                // Handled by the RemoteCallbackList
2117                            }
2118                        }
2119                        mTaskStackListeners.finishBroadcast();
2120                    }
2121                    break;
2122                }
2123            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2124                final int uid = msg.arg1;
2125                final byte[] firstPacket = (byte[]) msg.obj;
2126
2127                synchronized (mPidsSelfLocked) {
2128                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2129                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2130                        if (p.uid == uid) {
2131                            try {
2132                                p.thread.notifyCleartextNetwork(firstPacket);
2133                            } catch (RemoteException ignored) {
2134                            }
2135                        }
2136                    }
2137                }
2138                break;
2139            }
2140            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2141                final String procName;
2142                final int uid;
2143                final long memLimit;
2144                final String reportPackage;
2145                synchronized (ActivityManagerService.this) {
2146                    procName = mMemWatchDumpProcName;
2147                    uid = mMemWatchDumpUid;
2148                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2149                    if (val == null) {
2150                        val = mMemWatchProcesses.get(procName, 0);
2151                    }
2152                    if (val != null) {
2153                        memLimit = val.first;
2154                        reportPackage = val.second;
2155                    } else {
2156                        memLimit = 0;
2157                        reportPackage = null;
2158                    }
2159                }
2160                if (procName == null) {
2161                    return;
2162                }
2163
2164                if (DEBUG_PSS) Slog.d(TAG_PSS,
2165                        "Showing dump heap notification from " + procName + "/" + uid);
2166
2167                INotificationManager inm = NotificationManager.getService();
2168                if (inm == null) {
2169                    return;
2170                }
2171
2172                String text = mContext.getString(R.string.dump_heap_notification, procName);
2173
2174
2175                Intent deleteIntent = new Intent();
2176                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2177                Intent intent = new Intent();
2178                intent.setClassName("android", DumpHeapActivity.class.getName());
2179                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2180                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2181                if (reportPackage != null) {
2182                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2183                }
2184                int userId = UserHandle.getUserId(uid);
2185                Notification notification = new Notification.Builder(mContext)
2186                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2187                        .setWhen(0)
2188                        .setOngoing(true)
2189                        .setAutoCancel(true)
2190                        .setTicker(text)
2191                        .setColor(mContext.getColor(
2192                                com.android.internal.R.color.system_notification_accent_color))
2193                        .setContentTitle(text)
2194                        .setContentText(
2195                                mContext.getText(R.string.dump_heap_notification_detail))
2196                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2197                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2198                                new UserHandle(userId)))
2199                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2200                                deleteIntent, 0, UserHandle.SYSTEM))
2201                        .build();
2202
2203                try {
2204                    int[] outId = new int[1];
2205                    inm.enqueueNotificationWithTag("android", "android", null,
2206                            R.string.dump_heap_notification,
2207                            notification, outId, userId);
2208                } catch (RuntimeException e) {
2209                    Slog.w(ActivityManagerService.TAG,
2210                            "Error showing notification for dump heap", e);
2211                } catch (RemoteException e) {
2212                }
2213            } break;
2214            case DELETE_DUMPHEAP_MSG: {
2215                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2216                        DumpHeapActivity.JAVA_URI,
2217                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2218                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2219                        UserHandle.myUserId());
2220                synchronized (ActivityManagerService.this) {
2221                    mMemWatchDumpFile = null;
2222                    mMemWatchDumpProcName = null;
2223                    mMemWatchDumpPid = -1;
2224                    mMemWatchDumpUid = -1;
2225                }
2226            } break;
2227            case FOREGROUND_PROFILE_CHANGED_MSG: {
2228                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2229            } break;
2230            case REPORT_TIME_TRACKER_MSG: {
2231                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2232                tracker.deliverResult(mContext);
2233            } break;
2234            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2235                mUserController.dispatchUserSwitchComplete(msg.arg1);
2236            } break;
2237            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2238                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2239                try {
2240                    connection.shutdown();
2241                } catch (RemoteException e) {
2242                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2243                }
2244                // Only a UiAutomation can set this flag and now that
2245                // it is finished we make sure it is reset to its default.
2246                mUserIsMonkey = false;
2247            } break;
2248            case APP_BOOST_DEACTIVATE_MSG: {
2249                synchronized(ActivityManagerService.this) {
2250                    if (mIsBoosted) {
2251                        if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2252                            nativeMigrateFromBoost();
2253                            mIsBoosted = false;
2254                            mBoostStartTime = 0;
2255                        } else {
2256                            Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2257                            mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2258                        }
2259                    }
2260                }
2261            } break;
2262            case IDLE_UIDS_MSG: {
2263                idleUids();
2264            } break;
2265            case LOG_STACK_STATE: {
2266                synchronized (ActivityManagerService.this) {
2267                    mStackSupervisor.logStackState();
2268                }
2269            } break;
2270            case VR_MODE_CHANGE_MSG: {
2271                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2272                final ActivityRecord r = (ActivityRecord) msg.obj;
2273                boolean vrMode;
2274                ComponentName requestedPackage;
2275                ComponentName callingPackage;
2276                int userId;
2277                synchronized (ActivityManagerService.this) {
2278                    vrMode = r.requestedVrComponent != null;
2279                    requestedPackage = r.requestedVrComponent;
2280                    userId = r.userId;
2281                    callingPackage = r.info.getComponentName();
2282                    if (mInVrMode != vrMode) {
2283                        mInVrMode = vrMode;
2284                        mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2285                    }
2286                }
2287                vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2288            } break;
2289            case VR_MODE_APPLY_IF_NEEDED_MSG: {
2290                final ActivityRecord r = (ActivityRecord) msg.obj;
2291                final boolean needsVrMode = r != null && r.requestedVrComponent != null;
2292                if (needsVrMode) {
2293                    VrManagerInternal vrService =
2294                            LocalServices.getService(VrManagerInternal.class);
2295                    boolean enable = msg.arg1 == 1;
2296                    vrService.setVrMode(enable, r.requestedVrComponent, r.userId,
2297                            r.info.getComponentName());
2298                }
2299            } break;
2300            }
2301        }
2302    };
2303
2304    static final int COLLECT_PSS_BG_MSG = 1;
2305
2306    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2307        @Override
2308        public void handleMessage(Message msg) {
2309            switch (msg.what) {
2310            case COLLECT_PSS_BG_MSG: {
2311                long start = SystemClock.uptimeMillis();
2312                MemInfoReader memInfo = null;
2313                synchronized (ActivityManagerService.this) {
2314                    if (mFullPssPending) {
2315                        mFullPssPending = false;
2316                        memInfo = new MemInfoReader();
2317                    }
2318                }
2319                if (memInfo != null) {
2320                    updateCpuStatsNow();
2321                    long nativeTotalPss = 0;
2322                    synchronized (mProcessCpuTracker) {
2323                        final int N = mProcessCpuTracker.countStats();
2324                        for (int j=0; j<N; j++) {
2325                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2326                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2327                                // This is definitely an application process; skip it.
2328                                continue;
2329                            }
2330                            synchronized (mPidsSelfLocked) {
2331                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2332                                    // This is one of our own processes; skip it.
2333                                    continue;
2334                                }
2335                            }
2336                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2337                        }
2338                    }
2339                    memInfo.readMemInfo();
2340                    synchronized (ActivityManagerService.this) {
2341                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2342                                + (SystemClock.uptimeMillis()-start) + "ms");
2343                        final long cachedKb = memInfo.getCachedSizeKb();
2344                        final long freeKb = memInfo.getFreeSizeKb();
2345                        final long zramKb = memInfo.getZramTotalSizeKb();
2346                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2347                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2348                                kernelKb*1024, nativeTotalPss*1024);
2349                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2350                                nativeTotalPss);
2351                    }
2352                }
2353
2354                int num = 0;
2355                long[] tmp = new long[2];
2356                do {
2357                    ProcessRecord proc;
2358                    int procState;
2359                    int pid;
2360                    long lastPssTime;
2361                    synchronized (ActivityManagerService.this) {
2362                        if (mPendingPssProcesses.size() <= 0) {
2363                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2364                                    "Collected PSS of " + num + " processes in "
2365                                    + (SystemClock.uptimeMillis() - start) + "ms");
2366                            mPendingPssProcesses.clear();
2367                            return;
2368                        }
2369                        proc = mPendingPssProcesses.remove(0);
2370                        procState = proc.pssProcState;
2371                        lastPssTime = proc.lastPssTime;
2372                        if (proc.thread != null && procState == proc.setProcState
2373                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2374                                        < SystemClock.uptimeMillis()) {
2375                            pid = proc.pid;
2376                        } else {
2377                            proc = null;
2378                            pid = 0;
2379                        }
2380                    }
2381                    if (proc != null) {
2382                        long pss = Debug.getPss(pid, tmp, null);
2383                        synchronized (ActivityManagerService.this) {
2384                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2385                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2386                                num++;
2387                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2388                                        SystemClock.uptimeMillis());
2389                            }
2390                        }
2391                    }
2392                } while (true);
2393            }
2394            }
2395        }
2396    };
2397
2398    public void setSystemProcess() {
2399        try {
2400            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2401            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2402            ServiceManager.addService("meminfo", new MemBinder(this));
2403            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2404            ServiceManager.addService("dbinfo", new DbBinder(this));
2405            if (MONITOR_CPU_USAGE) {
2406                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2407            }
2408            ServiceManager.addService("permission", new PermissionController(this));
2409            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2410
2411            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2412                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2413            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2414
2415            synchronized (this) {
2416                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2417                app.persistent = true;
2418                app.pid = MY_PID;
2419                app.maxAdj = ProcessList.SYSTEM_ADJ;
2420                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2421                synchronized (mPidsSelfLocked) {
2422                    mPidsSelfLocked.put(app.pid, app);
2423                }
2424                updateLruProcessLocked(app, false, null);
2425                updateOomAdjLocked();
2426            }
2427        } catch (PackageManager.NameNotFoundException e) {
2428            throw new RuntimeException(
2429                    "Unable to find android system package", e);
2430        }
2431    }
2432
2433    public void setWindowManager(WindowManagerService wm) {
2434        mWindowManager = wm;
2435        mStackSupervisor.setWindowManager(wm);
2436        mActivityStarter.setWindowManager(wm);
2437    }
2438
2439    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2440        mUsageStatsService = usageStatsManager;
2441    }
2442
2443    public void startObservingNativeCrashes() {
2444        final NativeCrashListener ncl = new NativeCrashListener(this);
2445        ncl.start();
2446    }
2447
2448    public IAppOpsService getAppOpsService() {
2449        return mAppOpsService;
2450    }
2451
2452    static class MemBinder extends Binder {
2453        ActivityManagerService mActivityManagerService;
2454        MemBinder(ActivityManagerService activityManagerService) {
2455            mActivityManagerService = activityManagerService;
2456        }
2457
2458        @Override
2459        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2460            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2461                    != PackageManager.PERMISSION_GRANTED) {
2462                pw.println("Permission Denial: can't dump meminfo from from pid="
2463                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2464                        + " without permission " + android.Manifest.permission.DUMP);
2465                return;
2466            }
2467
2468            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2469        }
2470    }
2471
2472    static class GraphicsBinder extends Binder {
2473        ActivityManagerService mActivityManagerService;
2474        GraphicsBinder(ActivityManagerService activityManagerService) {
2475            mActivityManagerService = activityManagerService;
2476        }
2477
2478        @Override
2479        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2480            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2481                    != PackageManager.PERMISSION_GRANTED) {
2482                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2483                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2484                        + " without permission " + android.Manifest.permission.DUMP);
2485                return;
2486            }
2487
2488            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2489        }
2490    }
2491
2492    static class DbBinder extends Binder {
2493        ActivityManagerService mActivityManagerService;
2494        DbBinder(ActivityManagerService activityManagerService) {
2495            mActivityManagerService = activityManagerService;
2496        }
2497
2498        @Override
2499        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2500            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2501                    != PackageManager.PERMISSION_GRANTED) {
2502                pw.println("Permission Denial: can't dump dbinfo from from pid="
2503                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2504                        + " without permission " + android.Manifest.permission.DUMP);
2505                return;
2506            }
2507
2508            mActivityManagerService.dumpDbInfo(fd, pw, args);
2509        }
2510    }
2511
2512    static class CpuBinder extends Binder {
2513        ActivityManagerService mActivityManagerService;
2514        CpuBinder(ActivityManagerService activityManagerService) {
2515            mActivityManagerService = activityManagerService;
2516        }
2517
2518        @Override
2519        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2520            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2521                    != PackageManager.PERMISSION_GRANTED) {
2522                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2523                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2524                        + " without permission " + android.Manifest.permission.DUMP);
2525                return;
2526            }
2527
2528            synchronized (mActivityManagerService.mProcessCpuTracker) {
2529                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2530                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2531                        SystemClock.uptimeMillis()));
2532            }
2533        }
2534    }
2535
2536    public static final class Lifecycle extends SystemService {
2537        private final ActivityManagerService mService;
2538
2539        public Lifecycle(Context context) {
2540            super(context);
2541            mService = new ActivityManagerService(context);
2542        }
2543
2544        @Override
2545        public void onStart() {
2546            mService.start();
2547        }
2548
2549        public ActivityManagerService getService() {
2550            return mService;
2551        }
2552    }
2553
2554    // Note: This method is invoked on the main thread but may need to attach various
2555    // handlers to other threads.  So take care to be explicit about the looper.
2556    public ActivityManagerService(Context systemContext) {
2557        mContext = systemContext;
2558        mFactoryTest = FactoryTest.getMode();
2559        mSystemThread = ActivityThread.currentActivityThread();
2560
2561        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2562
2563        mHandlerThread = new ServiceThread(TAG,
2564                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2565        mHandlerThread.start();
2566        mHandler = new MainHandler(mHandlerThread.getLooper());
2567        mUiHandler = new UiHandler();
2568
2569        /* static; one-time init here */
2570        if (sKillHandler == null) {
2571            sKillThread = new ServiceThread(TAG + ":kill",
2572                    android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2573            sKillThread.start();
2574            sKillHandler = new KillHandler(sKillThread.getLooper());
2575        }
2576
2577        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2578                "foreground", BROADCAST_FG_TIMEOUT, false);
2579        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2580                "background", BROADCAST_BG_TIMEOUT, true);
2581        mBroadcastQueues[0] = mFgBroadcastQueue;
2582        mBroadcastQueues[1] = mBgBroadcastQueue;
2583
2584        mServices = new ActiveServices(this);
2585        mProviderMap = new ProviderMap(this);
2586        mAppErrors = new AppErrors(mContext, this);
2587
2588        // TODO: Move creation of battery stats service outside of activity manager service.
2589        File dataDir = Environment.getDataDirectory();
2590        File systemDir = new File(dataDir, "system");
2591        systemDir.mkdirs();
2592        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2593        mBatteryStatsService.getActiveStatistics().readLocked();
2594        mBatteryStatsService.scheduleWriteToDisk();
2595        mOnBattery = DEBUG_POWER ? true
2596                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2597        mBatteryStatsService.getActiveStatistics().setCallback(this);
2598
2599        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2600
2601        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2602        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2603                new IAppOpsCallback.Stub() {
2604                    @Override public void opChanged(int op, int uid, String packageName) {
2605                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2606                            if (mAppOpsService.checkOperation(op, uid, packageName)
2607                                    != AppOpsManager.MODE_ALLOWED) {
2608                                runInBackgroundDisabled(uid);
2609                            }
2610                        }
2611                    }
2612                });
2613
2614        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2615
2616        mUserController = new UserController(this);
2617
2618        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2619            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2620
2621        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2622
2623        mConfiguration.setToDefaults();
2624        mConfiguration.setLocales(LocaleList.getDefault());
2625
2626        mConfigurationSeq = mConfiguration.seq = 1;
2627        mProcessCpuTracker.init();
2628
2629        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2630        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2631        mStackSupervisor = new ActivityStackSupervisor(this);
2632        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2633        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2634
2635        mProcessCpuThread = new Thread("CpuTracker") {
2636            @Override
2637            public void run() {
2638                while (true) {
2639                    try {
2640                        try {
2641                            synchronized(this) {
2642                                final long now = SystemClock.uptimeMillis();
2643                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2644                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2645                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2646                                //        + ", write delay=" + nextWriteDelay);
2647                                if (nextWriteDelay < nextCpuDelay) {
2648                                    nextCpuDelay = nextWriteDelay;
2649                                }
2650                                if (nextCpuDelay > 0) {
2651                                    mProcessCpuMutexFree.set(true);
2652                                    this.wait(nextCpuDelay);
2653                                }
2654                            }
2655                        } catch (InterruptedException e) {
2656                        }
2657                        updateCpuStatsNow();
2658                    } catch (Exception e) {
2659                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2660                    }
2661                }
2662            }
2663        };
2664
2665        Watchdog.getInstance().addMonitor(this);
2666        Watchdog.getInstance().addThread(mHandler);
2667    }
2668
2669    public void setSystemServiceManager(SystemServiceManager mgr) {
2670        mSystemServiceManager = mgr;
2671    }
2672
2673    public void setInstaller(Installer installer) {
2674        mInstaller = installer;
2675    }
2676
2677    private void start() {
2678        Process.removeAllProcessGroups();
2679        mProcessCpuThread.start();
2680
2681        mBatteryStatsService.publish(mContext);
2682        mAppOpsService.publish(mContext);
2683        Slog.d("AppOps", "AppOpsService published");
2684        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2685    }
2686
2687    void onUserStoppedLocked(int userId) {
2688        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2689    }
2690
2691    public void initPowerManagement() {
2692        mStackSupervisor.initPowerManagement();
2693        mBatteryStatsService.initPowerManagement();
2694        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2695        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2696        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2697        mVoiceWakeLock.setReferenceCounted(false);
2698    }
2699
2700    @Override
2701    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2702            throws RemoteException {
2703        if (code == SYSPROPS_TRANSACTION) {
2704            // We need to tell all apps about the system property change.
2705            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2706            synchronized(this) {
2707                final int NP = mProcessNames.getMap().size();
2708                for (int ip=0; ip<NP; ip++) {
2709                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2710                    final int NA = apps.size();
2711                    for (int ia=0; ia<NA; ia++) {
2712                        ProcessRecord app = apps.valueAt(ia);
2713                        if (app.thread != null) {
2714                            procs.add(app.thread.asBinder());
2715                        }
2716                    }
2717                }
2718            }
2719
2720            int N = procs.size();
2721            for (int i=0; i<N; i++) {
2722                Parcel data2 = Parcel.obtain();
2723                try {
2724                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2725                } catch (RemoteException e) {
2726                }
2727                data2.recycle();
2728            }
2729        }
2730        try {
2731            return super.onTransact(code, data, reply, flags);
2732        } catch (RuntimeException e) {
2733            // The activity manager only throws security exceptions, so let's
2734            // log all others.
2735            if (!(e instanceof SecurityException)) {
2736                Slog.wtf(TAG, "Activity Manager Crash", e);
2737            }
2738            throw e;
2739        }
2740    }
2741
2742    void updateCpuStats() {
2743        final long now = SystemClock.uptimeMillis();
2744        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2745            return;
2746        }
2747        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2748            synchronized (mProcessCpuThread) {
2749                mProcessCpuThread.notify();
2750            }
2751        }
2752    }
2753
2754    void updateCpuStatsNow() {
2755        synchronized (mProcessCpuTracker) {
2756            mProcessCpuMutexFree.set(false);
2757            final long now = SystemClock.uptimeMillis();
2758            boolean haveNewCpuStats = false;
2759
2760            if (MONITOR_CPU_USAGE &&
2761                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2762                mLastCpuTime.set(now);
2763                mProcessCpuTracker.update();
2764                if (mProcessCpuTracker.hasGoodLastStats()) {
2765                    haveNewCpuStats = true;
2766                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2767                    //Slog.i(TAG, "Total CPU usage: "
2768                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2769
2770                    // Slog the cpu usage if the property is set.
2771                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2772                        int user = mProcessCpuTracker.getLastUserTime();
2773                        int system = mProcessCpuTracker.getLastSystemTime();
2774                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2775                        int irq = mProcessCpuTracker.getLastIrqTime();
2776                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2777                        int idle = mProcessCpuTracker.getLastIdleTime();
2778
2779                        int total = user + system + iowait + irq + softIrq + idle;
2780                        if (total == 0) total = 1;
2781
2782                        EventLog.writeEvent(EventLogTags.CPU,
2783                                ((user+system+iowait+irq+softIrq) * 100) / total,
2784                                (user * 100) / total,
2785                                (system * 100) / total,
2786                                (iowait * 100) / total,
2787                                (irq * 100) / total,
2788                                (softIrq * 100) / total);
2789                    }
2790                }
2791            }
2792
2793            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2794            synchronized(bstats) {
2795                synchronized(mPidsSelfLocked) {
2796                    if (haveNewCpuStats) {
2797                        if (bstats.startAddingCpuLocked()) {
2798                            int totalUTime = 0;
2799                            int totalSTime = 0;
2800                            final int N = mProcessCpuTracker.countStats();
2801                            for (int i=0; i<N; i++) {
2802                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2803                                if (!st.working) {
2804                                    continue;
2805                                }
2806                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2807                                totalUTime += st.rel_utime;
2808                                totalSTime += st.rel_stime;
2809                                if (pr != null) {
2810                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2811                                    if (ps == null || !ps.isActive()) {
2812                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2813                                                pr.info.uid, pr.processName);
2814                                    }
2815                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2816                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2817                                } else {
2818                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2819                                    if (ps == null || !ps.isActive()) {
2820                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2821                                                bstats.mapUid(st.uid), st.name);
2822                                    }
2823                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2824                                }
2825                            }
2826                            final int userTime = mProcessCpuTracker.getLastUserTime();
2827                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2828                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2829                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2830                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2831                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2832                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2833                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2834                        }
2835                    }
2836                }
2837
2838                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2839                    mLastWriteTime = now;
2840                    mBatteryStatsService.scheduleWriteToDisk();
2841                }
2842            }
2843        }
2844    }
2845
2846    @Override
2847    public void batteryNeedsCpuUpdate() {
2848        updateCpuStatsNow();
2849    }
2850
2851    @Override
2852    public void batteryPowerChanged(boolean onBattery) {
2853        // When plugging in, update the CPU stats first before changing
2854        // the plug state.
2855        updateCpuStatsNow();
2856        synchronized (this) {
2857            synchronized(mPidsSelfLocked) {
2858                mOnBattery = DEBUG_POWER ? true : onBattery;
2859            }
2860        }
2861    }
2862
2863    @Override
2864    public void batterySendBroadcast(Intent intent) {
2865        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2866                AppOpsManager.OP_NONE, null, false, false,
2867                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2868    }
2869
2870    /**
2871     * Initialize the application bind args. These are passed to each
2872     * process when the bindApplication() IPC is sent to the process. They're
2873     * lazily setup to make sure the services are running when they're asked for.
2874     */
2875    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2876        if (mAppBindArgs == null) {
2877            mAppBindArgs = new HashMap<>();
2878
2879            // Isolated processes won't get this optimization, so that we don't
2880            // violate the rules about which services they have access to.
2881            if (!isolated) {
2882                // Setup the application init args
2883                mAppBindArgs.put("package", ServiceManager.getService("package"));
2884                mAppBindArgs.put("window", ServiceManager.getService("window"));
2885                mAppBindArgs.put(Context.ALARM_SERVICE,
2886                        ServiceManager.getService(Context.ALARM_SERVICE));
2887            }
2888        }
2889        return mAppBindArgs;
2890    }
2891
2892    boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2893        if (r == null || mFocusedActivity == r) {
2894            return false;
2895        }
2896
2897        if (!r.isFocusable()) {
2898            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2899            return false;
2900        }
2901
2902        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2903
2904        final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2905        if (wasDoingSetFocusedActivity) Slog.w(TAG,
2906                "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2907        mDoingSetFocusedActivity = true;
2908
2909        final ActivityRecord last = mFocusedActivity;
2910        mFocusedActivity = r;
2911        if (r.task.isApplicationTask()) {
2912            if (mCurAppTimeTracker != r.appTimeTracker) {
2913                // We are switching app tracking.  Complete the current one.
2914                if (mCurAppTimeTracker != null) {
2915                    mCurAppTimeTracker.stop();
2916                    mHandler.obtainMessage(
2917                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2918                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2919                    mCurAppTimeTracker = null;
2920                }
2921                if (r.appTimeTracker != null) {
2922                    mCurAppTimeTracker = r.appTimeTracker;
2923                    startTimeTrackingFocusedActivityLocked();
2924                }
2925            } else {
2926                startTimeTrackingFocusedActivityLocked();
2927            }
2928        } else {
2929            r.appTimeTracker = null;
2930        }
2931        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2932        // TODO: Probably not, because we don't want to resume voice on switching
2933        // back to this activity
2934        if (r.task.voiceInteractor != null) {
2935            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2936        } else {
2937            finishRunningVoiceLocked();
2938            IVoiceInteractionSession session;
2939            if (last != null && ((session = last.task.voiceSession) != null
2940                    || (session = last.voiceSession) != null)) {
2941                // We had been in a voice interaction session, but now focused has
2942                // move to something different.  Just finish the session, we can't
2943                // return to it and retain the proper state and synchronization with
2944                // the voice interaction service.
2945                finishVoiceTask(session);
2946            }
2947        }
2948        if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
2949            mWindowManager.setFocusedApp(r.appToken, true);
2950        }
2951        applyUpdateLockStateLocked(r);
2952        applyUpdateVrModeLocked(r);
2953        if (mFocusedActivity.userId != mLastFocusedUserId) {
2954            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2955            mHandler.obtainMessage(
2956                    FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
2957            mLastFocusedUserId = mFocusedActivity.userId;
2958        }
2959
2960        // Log a warning if the focused app is changed during the process. This could
2961        // indicate a problem of the focus setting logic!
2962        if (mFocusedActivity != r) Slog.w(TAG,
2963                "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
2964        mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
2965
2966        EventLogTags.writeAmFocusedActivity(
2967                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2968                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
2969                reason);
2970        return true;
2971    }
2972
2973    final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
2974        if (mFocusedActivity != goingAway) {
2975            return;
2976        }
2977
2978        final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
2979        if (focusedStack != null) {
2980            final ActivityRecord top = focusedStack.topActivity();
2981            if (top != null && top.userId != mLastFocusedUserId) {
2982                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2983                mHandler.sendMessage(
2984                        mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
2985                mLastFocusedUserId = top.userId;
2986            }
2987        }
2988
2989        // Try to move focus to another activity if possible.
2990        if (setFocusedActivityLocked(
2991                focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
2992            return;
2993        }
2994
2995        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
2996                + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
2997        mFocusedActivity = null;
2998        EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
2999    }
3000
3001    @Override
3002    public void setFocusedStack(int stackId) {
3003        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3004        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3005        final long callingId = Binder.clearCallingIdentity();
3006        try {
3007            synchronized (this) {
3008                final ActivityStack stack = mStackSupervisor.getStack(stackId);
3009                if (stack == null) {
3010                    return;
3011                }
3012                final ActivityRecord r = stack.topRunningActivityLocked();
3013                if (setFocusedActivityLocked(r, "setFocusedStack")) {
3014                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3015                }
3016            }
3017        } finally {
3018            Binder.restoreCallingIdentity(callingId);
3019        }
3020    }
3021
3022    @Override
3023    public void setFocusedTask(int taskId) {
3024        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3025        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3026        final long callingId = Binder.clearCallingIdentity();
3027        try {
3028            synchronized (this) {
3029                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3030                if (task == null) {
3031                    return;
3032                }
3033                final ActivityRecord r = task.topRunningActivityLocked();
3034                if (setFocusedActivityLocked(r, "setFocusedTask")) {
3035                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3036                }
3037            }
3038        } finally {
3039            Binder.restoreCallingIdentity(callingId);
3040        }
3041    }
3042
3043    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3044    @Override
3045    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3046        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3047        synchronized (this) {
3048            if (listener != null) {
3049                mTaskStackListeners.register(listener);
3050            }
3051        }
3052    }
3053
3054    @Override
3055    public void notifyActivityDrawn(IBinder token) {
3056        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3057        synchronized (this) {
3058            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3059            if (r != null) {
3060                r.task.stack.notifyActivityDrawnLocked(r);
3061            }
3062        }
3063    }
3064
3065    final void applyUpdateLockStateLocked(ActivityRecord r) {
3066        // Modifications to the UpdateLock state are done on our handler, outside
3067        // the activity manager's locks.  The new state is determined based on the
3068        // state *now* of the relevant activity record.  The object is passed to
3069        // the handler solely for logging detail, not to be consulted/modified.
3070        final boolean nextState = r != null && r.immersive;
3071        mHandler.sendMessage(
3072                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3073    }
3074
3075    final void applyUpdateVrModeLocked(ActivityRecord r) {
3076        mHandler.sendMessage(
3077                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3078    }
3079
3080    private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
3081        mHandler.sendMessage(
3082                mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
3083    }
3084
3085    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3086        Message msg = Message.obtain();
3087        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3088        msg.obj = r.task.askedCompatMode ? null : r;
3089        mUiHandler.sendMessage(msg);
3090    }
3091
3092    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3093            String what, Object obj, ProcessRecord srcApp) {
3094        app.lastActivityTime = now;
3095
3096        if (app.activities.size() > 0) {
3097            // Don't want to touch dependent processes that are hosting activities.
3098            return index;
3099        }
3100
3101        int lrui = mLruProcesses.lastIndexOf(app);
3102        if (lrui < 0) {
3103            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3104                    + what + " " + obj + " from " + srcApp);
3105            return index;
3106        }
3107
3108        if (lrui >= index) {
3109            // Don't want to cause this to move dependent processes *back* in the
3110            // list as if they were less frequently used.
3111            return index;
3112        }
3113
3114        if (lrui >= mLruProcessActivityStart) {
3115            // Don't want to touch dependent processes that are hosting activities.
3116            return index;
3117        }
3118
3119        mLruProcesses.remove(lrui);
3120        if (index > 0) {
3121            index--;
3122        }
3123        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3124                + " in LRU list: " + app);
3125        mLruProcesses.add(index, app);
3126        return index;
3127    }
3128
3129    static void killProcessGroup(int uid, int pid) {
3130        if (sKillHandler != null) {
3131            sKillHandler.sendMessage(
3132                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3133        } else {
3134            Slog.w(TAG, "Asked to kill process group before system bringup!");
3135            Process.killProcessGroup(uid, pid);
3136        }
3137    }
3138
3139    final void removeLruProcessLocked(ProcessRecord app) {
3140        int lrui = mLruProcesses.lastIndexOf(app);
3141        if (lrui >= 0) {
3142            if (!app.killed) {
3143                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3144                Process.killProcessQuiet(app.pid);
3145                killProcessGroup(app.uid, app.pid);
3146            }
3147            if (lrui <= mLruProcessActivityStart) {
3148                mLruProcessActivityStart--;
3149            }
3150            if (lrui <= mLruProcessServiceStart) {
3151                mLruProcessServiceStart--;
3152            }
3153            mLruProcesses.remove(lrui);
3154        }
3155    }
3156
3157    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3158            ProcessRecord client) {
3159        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3160                || app.treatLikeActivity;
3161        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3162        if (!activityChange && hasActivity) {
3163            // The process has activities, so we are only allowing activity-based adjustments
3164            // to move it.  It should be kept in the front of the list with other
3165            // processes that have activities, and we don't want those to change their
3166            // order except due to activity operations.
3167            return;
3168        }
3169
3170        mLruSeq++;
3171        final long now = SystemClock.uptimeMillis();
3172        app.lastActivityTime = now;
3173
3174        // First a quick reject: if the app is already at the position we will
3175        // put it, then there is nothing to do.
3176        if (hasActivity) {
3177            final int N = mLruProcesses.size();
3178            if (N > 0 && mLruProcesses.get(N-1) == app) {
3179                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3180                return;
3181            }
3182        } else {
3183            if (mLruProcessServiceStart > 0
3184                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3185                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3186                return;
3187            }
3188        }
3189
3190        int lrui = mLruProcesses.lastIndexOf(app);
3191
3192        if (app.persistent && lrui >= 0) {
3193            // We don't care about the position of persistent processes, as long as
3194            // they are in the list.
3195            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3196            return;
3197        }
3198
3199        /* In progress: compute new position first, so we can avoid doing work
3200           if the process is not actually going to move.  Not yet working.
3201        int addIndex;
3202        int nextIndex;
3203        boolean inActivity = false, inService = false;
3204        if (hasActivity) {
3205            // Process has activities, put it at the very tipsy-top.
3206            addIndex = mLruProcesses.size();
3207            nextIndex = mLruProcessServiceStart;
3208            inActivity = true;
3209        } else if (hasService) {
3210            // Process has services, put it at the top of the service list.
3211            addIndex = mLruProcessActivityStart;
3212            nextIndex = mLruProcessServiceStart;
3213            inActivity = true;
3214            inService = true;
3215        } else  {
3216            // Process not otherwise of interest, it goes to the top of the non-service area.
3217            addIndex = mLruProcessServiceStart;
3218            if (client != null) {
3219                int clientIndex = mLruProcesses.lastIndexOf(client);
3220                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3221                        + app);
3222                if (clientIndex >= 0 && addIndex > clientIndex) {
3223                    addIndex = clientIndex;
3224                }
3225            }
3226            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3227        }
3228
3229        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3230                + mLruProcessActivityStart + "): " + app);
3231        */
3232
3233        if (lrui >= 0) {
3234            if (lrui < mLruProcessActivityStart) {
3235                mLruProcessActivityStart--;
3236            }
3237            if (lrui < mLruProcessServiceStart) {
3238                mLruProcessServiceStart--;
3239            }
3240            /*
3241            if (addIndex > lrui) {
3242                addIndex--;
3243            }
3244            if (nextIndex > lrui) {
3245                nextIndex--;
3246            }
3247            */
3248            mLruProcesses.remove(lrui);
3249        }
3250
3251        /*
3252        mLruProcesses.add(addIndex, app);
3253        if (inActivity) {
3254            mLruProcessActivityStart++;
3255        }
3256        if (inService) {
3257            mLruProcessActivityStart++;
3258        }
3259        */
3260
3261        int nextIndex;
3262        if (hasActivity) {
3263            final int N = mLruProcesses.size();
3264            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3265                // Process doesn't have activities, but has clients with
3266                // activities...  move it up, but one below the top (the top
3267                // should always have a real activity).
3268                if (DEBUG_LRU) Slog.d(TAG_LRU,
3269                        "Adding to second-top of LRU activity list: " + app);
3270                mLruProcesses.add(N - 1, app);
3271                // To keep it from spamming the LRU list (by making a bunch of clients),
3272                // we will push down any other entries owned by the app.
3273                final int uid = app.info.uid;
3274                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3275                    ProcessRecord subProc = mLruProcesses.get(i);
3276                    if (subProc.info.uid == uid) {
3277                        // We want to push this one down the list.  If the process after
3278                        // it is for the same uid, however, don't do so, because we don't
3279                        // want them internally to be re-ordered.
3280                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3281                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3282                                    "Pushing uid " + uid + " swapping at " + i + ": "
3283                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3284                            ProcessRecord tmp = mLruProcesses.get(i);
3285                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3286                            mLruProcesses.set(i - 1, tmp);
3287                            i--;
3288                        }
3289                    } else {
3290                        // A gap, we can stop here.
3291                        break;
3292                    }
3293                }
3294            } else {
3295                // Process has activities, put it at the very tipsy-top.
3296                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3297                mLruProcesses.add(app);
3298            }
3299            nextIndex = mLruProcessServiceStart;
3300        } else if (hasService) {
3301            // Process has services, put it at the top of the service list.
3302            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3303            mLruProcesses.add(mLruProcessActivityStart, app);
3304            nextIndex = mLruProcessServiceStart;
3305            mLruProcessActivityStart++;
3306        } else  {
3307            // Process not otherwise of interest, it goes to the top of the non-service area.
3308            int index = mLruProcessServiceStart;
3309            if (client != null) {
3310                // If there is a client, don't allow the process to be moved up higher
3311                // in the list than that client.
3312                int clientIndex = mLruProcesses.lastIndexOf(client);
3313                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3314                        + " when updating " + app);
3315                if (clientIndex <= lrui) {
3316                    // Don't allow the client index restriction to push it down farther in the
3317                    // list than it already is.
3318                    clientIndex = lrui;
3319                }
3320                if (clientIndex >= 0 && index > clientIndex) {
3321                    index = clientIndex;
3322                }
3323            }
3324            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3325            mLruProcesses.add(index, app);
3326            nextIndex = index-1;
3327            mLruProcessActivityStart++;
3328            mLruProcessServiceStart++;
3329        }
3330
3331        // If the app is currently using a content provider or service,
3332        // bump those processes as well.
3333        for (int j=app.connections.size()-1; j>=0; j--) {
3334            ConnectionRecord cr = app.connections.valueAt(j);
3335            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3336                    && cr.binding.service.app != null
3337                    && cr.binding.service.app.lruSeq != mLruSeq
3338                    && !cr.binding.service.app.persistent) {
3339                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3340                        "service connection", cr, app);
3341            }
3342        }
3343        for (int j=app.conProviders.size()-1; j>=0; j--) {
3344            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3345            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3346                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3347                        "provider reference", cpr, app);
3348            }
3349        }
3350    }
3351
3352    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3353        if (uid == Process.SYSTEM_UID) {
3354            // The system gets to run in any process.  If there are multiple
3355            // processes with the same uid, just pick the first (this
3356            // should never happen).
3357            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3358            if (procs == null) return null;
3359            final int procCount = procs.size();
3360            for (int i = 0; i < procCount; i++) {
3361                final int procUid = procs.keyAt(i);
3362                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3363                    // Don't use an app process or different user process for system component.
3364                    continue;
3365                }
3366                return procs.valueAt(i);
3367            }
3368        }
3369        ProcessRecord proc = mProcessNames.get(processName, uid);
3370        if (false && proc != null && !keepIfLarge
3371                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3372                && proc.lastCachedPss >= 4000) {
3373            // Turn this condition on to cause killing to happen regularly, for testing.
3374            if (proc.baseProcessTracker != null) {
3375                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3376            }
3377            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3378        } else if (proc != null && !keepIfLarge
3379                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3380                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3381            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3382            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3383                if (proc.baseProcessTracker != null) {
3384                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3385                }
3386                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3387            }
3388        }
3389        return proc;
3390    }
3391
3392    void notifyPackageUse(String packageName, int reason) {
3393        IPackageManager pm = AppGlobals.getPackageManager();
3394        try {
3395            pm.notifyPackageUse(packageName, reason);
3396        } catch (RemoteException e) {
3397        }
3398    }
3399
3400    boolean isNextTransitionForward() {
3401        int transit = mWindowManager.getPendingAppTransition();
3402        return transit == TRANSIT_ACTIVITY_OPEN
3403                || transit == TRANSIT_TASK_OPEN
3404                || transit == TRANSIT_TASK_TO_FRONT;
3405    }
3406
3407    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3408            String processName, String abiOverride, int uid, Runnable crashHandler) {
3409        synchronized(this) {
3410            ApplicationInfo info = new ApplicationInfo();
3411            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3412            // For isolated processes, the former contains the parent's uid and the latter the
3413            // actual uid of the isolated process.
3414            // In the special case introduced by this method (which is, starting an isolated
3415            // process directly from the SystemServer without an actual parent app process) the
3416            // closest thing to a parent's uid is SYSTEM_UID.
3417            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3418            // the |isolated| logic in the ProcessRecord constructor.
3419            info.uid = Process.SYSTEM_UID;
3420            info.processName = processName;
3421            info.className = entryPoint;
3422            info.packageName = "android";
3423            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3424                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3425                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3426                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3427                    crashHandler);
3428            return proc != null ? proc.pid : 0;
3429        }
3430    }
3431
3432    final ProcessRecord startProcessLocked(String processName,
3433            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3434            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3435            boolean isolated, boolean keepIfLarge) {
3436        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3437                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3438                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3439                null /* crashHandler */);
3440    }
3441
3442    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3443            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3444            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3445            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3446        long startTime = SystemClock.elapsedRealtime();
3447        ProcessRecord app;
3448        if (!isolated) {
3449            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3450            checkTime(startTime, "startProcess: after getProcessRecord");
3451
3452            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3453                // If we are in the background, then check to see if this process
3454                // is bad.  If so, we will just silently fail.
3455                if (mAppErrors.isBadProcessLocked(info)) {
3456                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3457                            + "/" + info.processName);
3458                    return null;
3459                }
3460            } else {
3461                // When the user is explicitly starting a process, then clear its
3462                // crash count so that we won't make it bad until they see at
3463                // least one crash dialog again, and make the process good again
3464                // if it had been bad.
3465                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3466                        + "/" + info.processName);
3467                mAppErrors.resetProcessCrashTimeLocked(info);
3468                if (mAppErrors.isBadProcessLocked(info)) {
3469                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3470                            UserHandle.getUserId(info.uid), info.uid,
3471                            info.processName);
3472                    mAppErrors.clearBadProcessLocked(info);
3473                    if (app != null) {
3474                        app.bad = false;
3475                    }
3476                }
3477            }
3478        } else {
3479            // If this is an isolated process, it can't re-use an existing process.
3480            app = null;
3481        }
3482
3483        // app launch boost for big.little configurations
3484        // use cpusets to migrate freshly launched tasks to big cores
3485        synchronized(ActivityManagerService.this) {
3486            nativeMigrateToBoost();
3487            mIsBoosted = true;
3488            mBoostStartTime = SystemClock.uptimeMillis();
3489            Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3490            mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3491        }
3492
3493        // We don't have to do anything more if:
3494        // (1) There is an existing application record; and
3495        // (2) The caller doesn't think it is dead, OR there is no thread
3496        //     object attached to it so we know it couldn't have crashed; and
3497        // (3) There is a pid assigned to it, so it is either starting or
3498        //     already running.
3499        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3500                + " app=" + app + " knownToBeDead=" + knownToBeDead
3501                + " thread=" + (app != null ? app.thread : null)
3502                + " pid=" + (app != null ? app.pid : -1));
3503        if (app != null && app.pid > 0) {
3504            if (!knownToBeDead || app.thread == null) {
3505                // We already have the app running, or are waiting for it to
3506                // come up (we have a pid but not yet its thread), so keep it.
3507                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3508                // If this is a new package in the process, add the package to the list
3509                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3510                checkTime(startTime, "startProcess: done, added package to proc");
3511                return app;
3512            }
3513
3514            // An application record is attached to a previous process,
3515            // clean it up now.
3516            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3517            checkTime(startTime, "startProcess: bad proc running, killing");
3518            killProcessGroup(app.uid, app.pid);
3519            handleAppDiedLocked(app, true, true);
3520            checkTime(startTime, "startProcess: done killing old proc");
3521        }
3522
3523        String hostingNameStr = hostingName != null
3524                ? hostingName.flattenToShortString() : null;
3525
3526        if (app == null) {
3527            checkTime(startTime, "startProcess: creating new process record");
3528            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3529            if (app == null) {
3530                Slog.w(TAG, "Failed making new process record for "
3531                        + processName + "/" + info.uid + " isolated=" + isolated);
3532                return null;
3533            }
3534            app.crashHandler = crashHandler;
3535            checkTime(startTime, "startProcess: done creating new process record");
3536        } else {
3537            // If this is a new package in the process, add the package to the list
3538            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3539            checkTime(startTime, "startProcess: added package to existing proc");
3540        }
3541
3542        // If the system is not ready yet, then hold off on starting this
3543        // process until it is.
3544        if (!mProcessesReady
3545                && !isAllowedWhileBooting(info)
3546                && !allowWhileBooting) {
3547            if (!mProcessesOnHold.contains(app)) {
3548                mProcessesOnHold.add(app);
3549            }
3550            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3551                    "System not ready, putting on hold: " + app);
3552            checkTime(startTime, "startProcess: returning with proc on hold");
3553            return app;
3554        }
3555
3556        checkTime(startTime, "startProcess: stepping in to startProcess");
3557        startProcessLocked(
3558                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3559        checkTime(startTime, "startProcess: done starting proc!");
3560        return (app.pid != 0) ? app : null;
3561    }
3562
3563    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3564        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3565    }
3566
3567    private final void startProcessLocked(ProcessRecord app,
3568            String hostingType, String hostingNameStr) {
3569        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3570                null /* entryPoint */, null /* entryPointArgs */);
3571    }
3572
3573    private final void startProcessLocked(ProcessRecord app, String hostingType,
3574            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3575        long startTime = SystemClock.elapsedRealtime();
3576        if (app.pid > 0 && app.pid != MY_PID) {
3577            checkTime(startTime, "startProcess: removing from pids map");
3578            synchronized (mPidsSelfLocked) {
3579                mPidsSelfLocked.remove(app.pid);
3580                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3581            }
3582            checkTime(startTime, "startProcess: done removing from pids map");
3583            app.setPid(0);
3584        }
3585
3586        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3587                "startProcessLocked removing on hold: " + app);
3588        mProcessesOnHold.remove(app);
3589
3590        checkTime(startTime, "startProcess: starting to update cpu stats");
3591        updateCpuStats();
3592        checkTime(startTime, "startProcess: done updating cpu stats");
3593
3594        try {
3595            try {
3596                final int userId = UserHandle.getUserId(app.uid);
3597                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3598            } catch (RemoteException e) {
3599                throw e.rethrowAsRuntimeException();
3600            }
3601
3602            int uid = app.uid;
3603            int[] gids = null;
3604            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3605            if (!app.isolated) {
3606                int[] permGids = null;
3607                try {
3608                    checkTime(startTime, "startProcess: getting gids from package manager");
3609                    final IPackageManager pm = AppGlobals.getPackageManager();
3610                    permGids = pm.getPackageGids(app.info.packageName,
3611                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3612                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3613                            MountServiceInternal.class);
3614                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3615                            app.info.packageName);
3616                } catch (RemoteException e) {
3617                    throw e.rethrowAsRuntimeException();
3618                }
3619
3620                /*
3621                 * Add shared application and profile GIDs so applications can share some
3622                 * resources like shared libraries and access user-wide resources
3623                 */
3624                if (ArrayUtils.isEmpty(permGids)) {
3625                    gids = new int[2];
3626                } else {
3627                    gids = new int[permGids.length + 2];
3628                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3629                }
3630                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3631                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3632            }
3633            checkTime(startTime, "startProcess: building args");
3634            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3635                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3636                        && mTopComponent != null
3637                        && app.processName.equals(mTopComponent.getPackageName())) {
3638                    uid = 0;
3639                }
3640                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3641                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3642                    uid = 0;
3643                }
3644            }
3645            int debugFlags = 0;
3646            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3647                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3648                // Also turn on CheckJNI for debuggable apps. It's quite
3649                // awkward to turn on otherwise.
3650                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3651            }
3652            // Run the app in safe mode if its manifest requests so or the
3653            // system is booted in safe mode.
3654            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3655                mSafeMode == true) {
3656                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3657            }
3658            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3659                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3660            }
3661            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3662            if ("true".equals(genDebugInfoProperty)) {
3663                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3664            }
3665            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3666                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3667            }
3668            if ("1".equals(SystemProperties.get("debug.assert"))) {
3669                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3670            }
3671            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3672                // Enable all debug flags required by the native debugger.
3673                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3674                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3675                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3676                mNativeDebuggingApp = null;
3677            }
3678
3679            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3680            if (requiredAbi == null) {
3681                requiredAbi = Build.SUPPORTED_ABIS[0];
3682            }
3683
3684            String instructionSet = null;
3685            if (app.info.primaryCpuAbi != null) {
3686                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3687            }
3688
3689            app.gids = gids;
3690            app.requiredAbi = requiredAbi;
3691            app.instructionSet = instructionSet;
3692
3693            // Start the process.  It will either succeed and return a result containing
3694            // the PID of the new process, or else throw a RuntimeException.
3695            boolean isActivityProcess = (entryPoint == null);
3696            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3697            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3698                    app.processName);
3699            checkTime(startTime, "startProcess: asking zygote to start proc");
3700            Process.ProcessStartResult startResult = Process.start(entryPoint,
3701                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3702                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3703                    app.info.dataDir, entryPointArgs);
3704            checkTime(startTime, "startProcess: returned from zygote!");
3705            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3706
3707            if (app.isolated) {
3708                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3709            }
3710            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3711            checkTime(startTime, "startProcess: done updating battery stats");
3712
3713            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3714                    UserHandle.getUserId(uid), startResult.pid, uid,
3715                    app.processName, hostingType,
3716                    hostingNameStr != null ? hostingNameStr : "");
3717
3718            try {
3719                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3720                        app.info.seinfo, app.info.sourceDir, startResult.pid);
3721            } catch (RemoteException ex) {
3722                // Ignore
3723            }
3724
3725            if (app.persistent) {
3726                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3727            }
3728
3729            checkTime(startTime, "startProcess: building log message");
3730            StringBuilder buf = mStringBuilder;
3731            buf.setLength(0);
3732            buf.append("Start proc ");
3733            buf.append(startResult.pid);
3734            buf.append(':');
3735            buf.append(app.processName);
3736            buf.append('/');
3737            UserHandle.formatUid(buf, uid);
3738            if (!isActivityProcess) {
3739                buf.append(" [");
3740                buf.append(entryPoint);
3741                buf.append("]");
3742            }
3743            buf.append(" for ");
3744            buf.append(hostingType);
3745            if (hostingNameStr != null) {
3746                buf.append(" ");
3747                buf.append(hostingNameStr);
3748            }
3749            Slog.i(TAG, buf.toString());
3750            app.setPid(startResult.pid);
3751            app.usingWrapper = startResult.usingWrapper;
3752            app.removed = false;
3753            app.killed = false;
3754            app.killedByAm = false;
3755            checkTime(startTime, "startProcess: starting to update pids map");
3756            synchronized (mPidsSelfLocked) {
3757                this.mPidsSelfLocked.put(startResult.pid, app);
3758                if (isActivityProcess) {
3759                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3760                    msg.obj = app;
3761                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3762                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3763                }
3764            }
3765            checkTime(startTime, "startProcess: done updating pids map");
3766        } catch (RuntimeException e) {
3767            Slog.e(TAG, "Failure starting process " + app.processName, e);
3768
3769            // Something went very wrong while trying to start this process; one
3770            // common case is when the package is frozen due to an active
3771            // upgrade. To recover, clean up any active bookkeeping related to
3772            // starting this process. (We already invoked this method once when
3773            // the package was initially frozen through KILL_APPLICATION_MSG, so
3774            // it doesn't hurt to use it again.)
3775            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3776                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3777        }
3778    }
3779
3780    void updateUsageStats(ActivityRecord component, boolean resumed) {
3781        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3782                "updateUsageStats: comp=" + component + "res=" + resumed);
3783        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3784        if (resumed) {
3785            if (mUsageStatsService != null) {
3786                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3787                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3788            }
3789            synchronized (stats) {
3790                stats.noteActivityResumedLocked(component.app.uid);
3791            }
3792        } else {
3793            if (mUsageStatsService != null) {
3794                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3795                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3796            }
3797            synchronized (stats) {
3798                stats.noteActivityPausedLocked(component.app.uid);
3799            }
3800        }
3801    }
3802
3803    Intent getHomeIntent() {
3804        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3805        intent.setComponent(mTopComponent);
3806        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3807        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3808            intent.addCategory(Intent.CATEGORY_HOME);
3809        }
3810        return intent;
3811    }
3812
3813    boolean startHomeActivityLocked(int userId, String reason) {
3814        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3815                && mTopAction == null) {
3816            // We are running in factory test mode, but unable to find
3817            // the factory test app, so just sit around displaying the
3818            // error message and don't try to start anything.
3819            return false;
3820        }
3821        Intent intent = getHomeIntent();
3822        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3823        if (aInfo != null) {
3824            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3825            // Don't do this if the home app is currently being
3826            // instrumented.
3827            aInfo = new ActivityInfo(aInfo);
3828            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3829            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3830                    aInfo.applicationInfo.uid, true);
3831            if (app == null || app.instrumentationClass == null) {
3832                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3833                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3834            }
3835        } else {
3836            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3837        }
3838
3839        return true;
3840    }
3841
3842    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3843        ActivityInfo ai = null;
3844        ComponentName comp = intent.getComponent();
3845        try {
3846            if (comp != null) {
3847                // Factory test.
3848                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3849            } else {
3850                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3851                        intent,
3852                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3853                        flags, userId);
3854
3855                if (info != null) {
3856                    ai = info.activityInfo;
3857                }
3858            }
3859        } catch (RemoteException e) {
3860            // ignore
3861        }
3862
3863        return ai;
3864    }
3865
3866    /**
3867     * Starts the "new version setup screen" if appropriate.
3868     */
3869    void startSetupActivityLocked() {
3870        // Only do this once per boot.
3871        if (mCheckedForSetup) {
3872            return;
3873        }
3874
3875        // We will show this screen if the current one is a different
3876        // version than the last one shown, and we are not running in
3877        // low-level factory test mode.
3878        final ContentResolver resolver = mContext.getContentResolver();
3879        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3880                Settings.Global.getInt(resolver,
3881                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3882            mCheckedForSetup = true;
3883
3884            // See if we should be showing the platform update setup UI.
3885            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3886            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3887                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3888            if (!ris.isEmpty()) {
3889                final ResolveInfo ri = ris.get(0);
3890                String vers = ri.activityInfo.metaData != null
3891                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3892                        : null;
3893                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3894                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3895                            Intent.METADATA_SETUP_VERSION);
3896                }
3897                String lastVers = Settings.Secure.getString(
3898                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3899                if (vers != null && !vers.equals(lastVers)) {
3900                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3901                    intent.setComponent(new ComponentName(
3902                            ri.activityInfo.packageName, ri.activityInfo.name));
3903                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3904                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3905                            null, 0, 0, 0, null, false, false, null, null, null);
3906                }
3907            }
3908        }
3909    }
3910
3911    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3912        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3913    }
3914
3915    void enforceNotIsolatedCaller(String caller) {
3916        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3917            throw new SecurityException("Isolated process not allowed to call " + caller);
3918        }
3919    }
3920
3921    void enforceShellRestriction(String restriction, int userHandle) {
3922        if (Binder.getCallingUid() == Process.SHELL_UID) {
3923            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3924                throw new SecurityException("Shell does not have permission to access user "
3925                        + userHandle);
3926            }
3927        }
3928    }
3929
3930    @Override
3931    public int getFrontActivityScreenCompatMode() {
3932        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3933        synchronized (this) {
3934            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3935        }
3936    }
3937
3938    @Override
3939    public void setFrontActivityScreenCompatMode(int mode) {
3940        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3941                "setFrontActivityScreenCompatMode");
3942        synchronized (this) {
3943            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3944        }
3945    }
3946
3947    @Override
3948    public int getPackageScreenCompatMode(String packageName) {
3949        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3950        synchronized (this) {
3951            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3952        }
3953    }
3954
3955    @Override
3956    public void setPackageScreenCompatMode(String packageName, int mode) {
3957        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3958                "setPackageScreenCompatMode");
3959        synchronized (this) {
3960            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3961        }
3962    }
3963
3964    @Override
3965    public boolean getPackageAskScreenCompat(String packageName) {
3966        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3967        synchronized (this) {
3968            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3969        }
3970    }
3971
3972    @Override
3973    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3974        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3975                "setPackageAskScreenCompat");
3976        synchronized (this) {
3977            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3978        }
3979    }
3980
3981    private boolean hasUsageStatsPermission(String callingPackage) {
3982        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3983                Binder.getCallingUid(), callingPackage);
3984        if (mode == AppOpsManager.MODE_DEFAULT) {
3985            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3986                    == PackageManager.PERMISSION_GRANTED;
3987        }
3988        return mode == AppOpsManager.MODE_ALLOWED;
3989    }
3990
3991    @Override
3992    public int getPackageProcessState(String packageName, String callingPackage) {
3993        if (!hasUsageStatsPermission(callingPackage)) {
3994            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3995                    "getPackageProcessState");
3996        }
3997
3998        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3999        synchronized (this) {
4000            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4001                final ProcessRecord proc = mLruProcesses.get(i);
4002                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
4003                        || procState > proc.setProcState) {
4004                    boolean found = false;
4005                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
4006                        if (proc.pkgList.keyAt(j).equals(packageName)) {
4007                            procState = proc.setProcState;
4008                            found = true;
4009                        }
4010                    }
4011                    if (proc.pkgDeps != null && !found) {
4012                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
4013                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
4014                                procState = proc.setProcState;
4015                                break;
4016                            }
4017                        }
4018                    }
4019                }
4020            }
4021        }
4022        return procState;
4023    }
4024
4025    @Override
4026    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
4027        synchronized (this) {
4028            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4029            if (app == null) {
4030                return false;
4031            }
4032            if (app.trimMemoryLevel < level && app.thread != null &&
4033                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4034                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4035                try {
4036                    app.thread.scheduleTrimMemory(level);
4037                    app.trimMemoryLevel = level;
4038                    return true;
4039                } catch (RemoteException e) {
4040                    // Fallthrough to failure case.
4041                }
4042            }
4043        }
4044        return false;
4045    }
4046
4047    private void dispatchProcessesChanged() {
4048        int N;
4049        synchronized (this) {
4050            N = mPendingProcessChanges.size();
4051            if (mActiveProcessChanges.length < N) {
4052                mActiveProcessChanges = new ProcessChangeItem[N];
4053            }
4054            mPendingProcessChanges.toArray(mActiveProcessChanges);
4055            mPendingProcessChanges.clear();
4056            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4057                    "*** Delivering " + N + " process changes");
4058        }
4059
4060        int i = mProcessObservers.beginBroadcast();
4061        while (i > 0) {
4062            i--;
4063            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4064            if (observer != null) {
4065                try {
4066                    for (int j=0; j<N; j++) {
4067                        ProcessChangeItem item = mActiveProcessChanges[j];
4068                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4069                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4070                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4071                                    + item.uid + ": " + item.foregroundActivities);
4072                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4073                                    item.foregroundActivities);
4074                        }
4075                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4076                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4077                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4078                                    + ": " + item.processState);
4079                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4080                        }
4081                    }
4082                } catch (RemoteException e) {
4083                }
4084            }
4085        }
4086        mProcessObservers.finishBroadcast();
4087
4088        synchronized (this) {
4089            for (int j=0; j<N; j++) {
4090                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4091            }
4092        }
4093    }
4094
4095    private void dispatchProcessDied(int pid, int uid) {
4096        int i = mProcessObservers.beginBroadcast();
4097        while (i > 0) {
4098            i--;
4099            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4100            if (observer != null) {
4101                try {
4102                    observer.onProcessDied(pid, uid);
4103                } catch (RemoteException e) {
4104                }
4105            }
4106        }
4107        mProcessObservers.finishBroadcast();
4108    }
4109
4110    private void dispatchUidsChanged() {
4111        int N;
4112        synchronized (this) {
4113            N = mPendingUidChanges.size();
4114            if (mActiveUidChanges.length < N) {
4115                mActiveUidChanges = new UidRecord.ChangeItem[N];
4116            }
4117            for (int i=0; i<N; i++) {
4118                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4119                mActiveUidChanges[i] = change;
4120                if (change.uidRecord != null) {
4121                    change.uidRecord.pendingChange = null;
4122                    change.uidRecord = null;
4123                }
4124            }
4125            mPendingUidChanges.clear();
4126            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4127                    "*** Delivering " + N + " uid changes");
4128        }
4129
4130        if (mLocalPowerManager != null) {
4131            for (int j=0; j<N; j++) {
4132                UidRecord.ChangeItem item = mActiveUidChanges[j];
4133                if (item.change == UidRecord.CHANGE_GONE
4134                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
4135                    mLocalPowerManager.uidGone(item.uid);
4136                } else {
4137                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4138                }
4139            }
4140        }
4141
4142        int i = mUidObservers.beginBroadcast();
4143        while (i > 0) {
4144            i--;
4145            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4146            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4147            if (observer != null) {
4148                try {
4149                    for (int j=0; j<N; j++) {
4150                        UidRecord.ChangeItem item = mActiveUidChanges[j];
4151                        final int change = item.change;
4152                        UidRecord validateUid = null;
4153                        if (VALIDATE_UID_STATES && i == 0) {
4154                            validateUid = mValidateUids.get(item.uid);
4155                            if (validateUid == null && change != UidRecord.CHANGE_GONE
4156                                    && change != UidRecord.CHANGE_GONE_IDLE) {
4157                                validateUid = new UidRecord(item.uid);
4158                                mValidateUids.put(item.uid, validateUid);
4159                            }
4160                        }
4161                        if (change == UidRecord.CHANGE_IDLE
4162                                || change == UidRecord.CHANGE_GONE_IDLE) {
4163                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4164                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4165                                        "UID idle uid=" + item.uid);
4166                                observer.onUidIdle(item.uid);
4167                            }
4168                            if (VALIDATE_UID_STATES && i == 0) {
4169                                if (validateUid != null) {
4170                                    validateUid.idle = true;
4171                                }
4172                            }
4173                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4174                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4175                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4176                                        "UID active uid=" + item.uid);
4177                                observer.onUidActive(item.uid);
4178                            }
4179                            if (VALIDATE_UID_STATES && i == 0) {
4180                                validateUid.idle = false;
4181                            }
4182                        }
4183                        if (change == UidRecord.CHANGE_GONE
4184                                || change == UidRecord.CHANGE_GONE_IDLE) {
4185                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4186                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4187                                        "UID gone uid=" + item.uid);
4188                                observer.onUidGone(item.uid);
4189                            }
4190                            if (VALIDATE_UID_STATES && i == 0) {
4191                                if (validateUid != null) {
4192                                    mValidateUids.remove(item.uid);
4193                                }
4194                            }
4195                        } else {
4196                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4197                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4198                                        "UID CHANGED uid=" + item.uid
4199                                                + ": " + item.processState);
4200                                observer.onUidStateChanged(item.uid, item.processState);
4201                            }
4202                            if (VALIDATE_UID_STATES && i == 0) {
4203                                validateUid.curProcState = validateUid.setProcState
4204                                        = item.processState;
4205                            }
4206                        }
4207                    }
4208                } catch (RemoteException e) {
4209                }
4210            }
4211        }
4212        mUidObservers.finishBroadcast();
4213
4214        synchronized (this) {
4215            for (int j=0; j<N; j++) {
4216                mAvailUidChanges.add(mActiveUidChanges[j]);
4217            }
4218        }
4219    }
4220
4221    @Override
4222    public final int startActivity(IApplicationThread caller, String callingPackage,
4223            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4224            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4225        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4226                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4227                UserHandle.getCallingUserId());
4228    }
4229
4230    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4231        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4232        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4233                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4234                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4235
4236        // TODO: Switch to user app stacks here.
4237        String mimeType = intent.getType();
4238        final Uri data = intent.getData();
4239        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4240            mimeType = getProviderMimeType(data, userId);
4241        }
4242        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4243
4244        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4245        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4246                null, 0, 0, null, null, null, null, false, userId, container, null);
4247    }
4248
4249    @Override
4250    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4251            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4252            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4253        enforceNotIsolatedCaller("startActivity");
4254        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4255                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4256        // TODO: Switch to user app stacks here.
4257        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4258                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4259                profilerInfo, null, null, bOptions, false, userId, null, null);
4260    }
4261
4262    @Override
4263    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4264            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4265            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4266            int userId) {
4267
4268        // This is very dangerous -- it allows you to perform a start activity (including
4269        // permission grants) as any app that may launch one of your own activities.  So
4270        // we will only allow this to be done from activities that are part of the core framework,
4271        // and then only when they are running as the system.
4272        final ActivityRecord sourceRecord;
4273        final int targetUid;
4274        final String targetPackage;
4275        synchronized (this) {
4276            if (resultTo == null) {
4277                throw new SecurityException("Must be called from an activity");
4278            }
4279            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4280            if (sourceRecord == null) {
4281                throw new SecurityException("Called with bad activity token: " + resultTo);
4282            }
4283            if (!sourceRecord.info.packageName.equals("android")) {
4284                throw new SecurityException(
4285                        "Must be called from an activity that is declared in the android package");
4286            }
4287            if (sourceRecord.app == null) {
4288                throw new SecurityException("Called without a process attached to activity");
4289            }
4290            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4291                // This is still okay, as long as this activity is running under the
4292                // uid of the original calling activity.
4293                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4294                    throw new SecurityException(
4295                            "Calling activity in uid " + sourceRecord.app.uid
4296                                    + " must be system uid or original calling uid "
4297                                    + sourceRecord.launchedFromUid);
4298                }
4299            }
4300            if (ignoreTargetSecurity) {
4301                if (intent.getComponent() == null) {
4302                    throw new SecurityException(
4303                            "Component must be specified with ignoreTargetSecurity");
4304                }
4305                if (intent.getSelector() != null) {
4306                    throw new SecurityException(
4307                            "Selector not allowed with ignoreTargetSecurity");
4308                }
4309            }
4310            targetUid = sourceRecord.launchedFromUid;
4311            targetPackage = sourceRecord.launchedFromPackage;
4312        }
4313
4314        if (userId == UserHandle.USER_NULL) {
4315            userId = UserHandle.getUserId(sourceRecord.app.uid);
4316        }
4317
4318        // TODO: Switch to user app stacks here.
4319        try {
4320            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4321                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4322                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4323            return ret;
4324        } catch (SecurityException e) {
4325            // XXX need to figure out how to propagate to original app.
4326            // A SecurityException here is generally actually a fault of the original
4327            // calling activity (such as a fairly granting permissions), so propagate it
4328            // back to them.
4329            /*
4330            StringBuilder msg = new StringBuilder();
4331            msg.append("While launching");
4332            msg.append(intent.toString());
4333            msg.append(": ");
4334            msg.append(e.getMessage());
4335            */
4336            throw e;
4337        }
4338    }
4339
4340    @Override
4341    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4342            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4343            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4344        enforceNotIsolatedCaller("startActivityAndWait");
4345        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4346                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4347        WaitResult res = new WaitResult();
4348        // TODO: Switch to user app stacks here.
4349        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4350                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4351                bOptions, false, userId, null, null);
4352        return res;
4353    }
4354
4355    @Override
4356    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4357            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4358            int startFlags, Configuration config, Bundle bOptions, int userId) {
4359        enforceNotIsolatedCaller("startActivityWithConfig");
4360        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4361                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4362        // TODO: Switch to user app stacks here.
4363        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4364                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4365                null, null, config, bOptions, false, userId, null, null);
4366        return ret;
4367    }
4368
4369    @Override
4370    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4371            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4372            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4373            throws TransactionTooLargeException {
4374        enforceNotIsolatedCaller("startActivityIntentSender");
4375        // Refuse possible leaked file descriptors
4376        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4377            throw new IllegalArgumentException("File descriptors passed in Intent");
4378        }
4379
4380        IIntentSender sender = intent.getTarget();
4381        if (!(sender instanceof PendingIntentRecord)) {
4382            throw new IllegalArgumentException("Bad PendingIntent object");
4383        }
4384
4385        PendingIntentRecord pir = (PendingIntentRecord)sender;
4386
4387        synchronized (this) {
4388            // If this is coming from the currently resumed activity, it is
4389            // effectively saying that app switches are allowed at this point.
4390            final ActivityStack stack = getFocusedStack();
4391            if (stack.mResumedActivity != null &&
4392                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4393                mAppSwitchesAllowedTime = 0;
4394            }
4395        }
4396        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4397                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4398        return ret;
4399    }
4400
4401    @Override
4402    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4403            Intent intent, String resolvedType, IVoiceInteractionSession session,
4404            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4405            Bundle bOptions, int userId) {
4406        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4407                != PackageManager.PERMISSION_GRANTED) {
4408            String msg = "Permission Denial: startVoiceActivity() from pid="
4409                    + Binder.getCallingPid()
4410                    + ", uid=" + Binder.getCallingUid()
4411                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4412            Slog.w(TAG, msg);
4413            throw new SecurityException(msg);
4414        }
4415        if (session == null || interactor == null) {
4416            throw new NullPointerException("null session or interactor");
4417        }
4418        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4419                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4420        // TODO: Switch to user app stacks here.
4421        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4422                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4423                null, bOptions, false, userId, null, null);
4424    }
4425
4426    @Override
4427    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4428            throws RemoteException {
4429        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4430        synchronized (this) {
4431            ActivityRecord activity = getFocusedStack().topActivity();
4432            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4433                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4434            }
4435            if (mRunningVoice != null || activity.task.voiceSession != null
4436                    || activity.voiceSession != null) {
4437                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4438                return;
4439            }
4440            if (activity.pendingVoiceInteractionStart) {
4441                Slog.w(TAG, "Pending start of voice interaction already.");
4442                return;
4443            }
4444            activity.pendingVoiceInteractionStart = true;
4445        }
4446        LocalServices.getService(VoiceInteractionManagerInternal.class)
4447                .startLocalVoiceInteraction(callingActivity, options);
4448    }
4449
4450    @Override
4451    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4452        LocalServices.getService(VoiceInteractionManagerInternal.class)
4453                .stopLocalVoiceInteraction(callingActivity);
4454    }
4455
4456    @Override
4457    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4458        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4459                .supportsLocalVoiceInteraction();
4460    }
4461
4462    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4463            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4464        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4465        if (activityToCallback == null) return;
4466        activityToCallback.setVoiceSessionLocked(voiceSession);
4467
4468        // Inform the activity
4469        try {
4470            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4471                    voiceInteractor);
4472            long token = Binder.clearCallingIdentity();
4473            try {
4474                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4475            } finally {
4476                Binder.restoreCallingIdentity(token);
4477            }
4478            // TODO: VI Should we cache the activity so that it's easier to find later
4479            // rather than scan through all the stacks and activities?
4480        } catch (RemoteException re) {
4481            activityToCallback.clearVoiceSessionLocked();
4482            // TODO: VI Should this terminate the voice session?
4483        }
4484    }
4485
4486    @Override
4487    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4488        synchronized (this) {
4489            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4490                if (keepAwake) {
4491                    mVoiceWakeLock.acquire();
4492                } else {
4493                    mVoiceWakeLock.release();
4494                }
4495            }
4496        }
4497    }
4498
4499    @Override
4500    public boolean startNextMatchingActivity(IBinder callingActivity,
4501            Intent intent, Bundle bOptions) {
4502        // Refuse possible leaked file descriptors
4503        if (intent != null && intent.hasFileDescriptors() == true) {
4504            throw new IllegalArgumentException("File descriptors passed in Intent");
4505        }
4506        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4507
4508        synchronized (this) {
4509            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4510            if (r == null) {
4511                ActivityOptions.abort(options);
4512                return false;
4513            }
4514            if (r.app == null || r.app.thread == null) {
4515                // The caller is not running...  d'oh!
4516                ActivityOptions.abort(options);
4517                return false;
4518            }
4519            intent = new Intent(intent);
4520            // The caller is not allowed to change the data.
4521            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4522            // And we are resetting to find the next component...
4523            intent.setComponent(null);
4524
4525            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4526
4527            ActivityInfo aInfo = null;
4528            try {
4529                List<ResolveInfo> resolves =
4530                    AppGlobals.getPackageManager().queryIntentActivities(
4531                            intent, r.resolvedType,
4532                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4533                            UserHandle.getCallingUserId()).getList();
4534
4535                // Look for the original activity in the list...
4536                final int N = resolves != null ? resolves.size() : 0;
4537                for (int i=0; i<N; i++) {
4538                    ResolveInfo rInfo = resolves.get(i);
4539                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4540                            && rInfo.activityInfo.name.equals(r.info.name)) {
4541                        // We found the current one...  the next matching is
4542                        // after it.
4543                        i++;
4544                        if (i<N) {
4545                            aInfo = resolves.get(i).activityInfo;
4546                        }
4547                        if (debug) {
4548                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4549                                    + "/" + r.info.name);
4550                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4551                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4552                        }
4553                        break;
4554                    }
4555                }
4556            } catch (RemoteException e) {
4557            }
4558
4559            if (aInfo == null) {
4560                // Nobody who is next!
4561                ActivityOptions.abort(options);
4562                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4563                return false;
4564            }
4565
4566            intent.setComponent(new ComponentName(
4567                    aInfo.applicationInfo.packageName, aInfo.name));
4568            intent.setFlags(intent.getFlags()&~(
4569                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4570                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4571                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4572                    Intent.FLAG_ACTIVITY_NEW_TASK));
4573
4574            // Okay now we need to start the new activity, replacing the
4575            // currently running activity.  This is a little tricky because
4576            // we want to start the new one as if the current one is finished,
4577            // but not finish the current one first so that there is no flicker.
4578            // And thus...
4579            final boolean wasFinishing = r.finishing;
4580            r.finishing = true;
4581
4582            // Propagate reply information over to the new activity.
4583            final ActivityRecord resultTo = r.resultTo;
4584            final String resultWho = r.resultWho;
4585            final int requestCode = r.requestCode;
4586            r.resultTo = null;
4587            if (resultTo != null) {
4588                resultTo.removeResultsLocked(r, resultWho, requestCode);
4589            }
4590
4591            final long origId = Binder.clearCallingIdentity();
4592            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4593                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4594                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4595                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4596                    false, false, null, null, null);
4597            Binder.restoreCallingIdentity(origId);
4598
4599            r.finishing = wasFinishing;
4600            if (res != ActivityManager.START_SUCCESS) {
4601                return false;
4602            }
4603            return true;
4604        }
4605    }
4606
4607    @Override
4608    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4609        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4610            String msg = "Permission Denial: startActivityFromRecents called without " +
4611                    START_TASKS_FROM_RECENTS;
4612            Slog.w(TAG, msg);
4613            throw new SecurityException(msg);
4614        }
4615        final long origId = Binder.clearCallingIdentity();
4616        try {
4617            synchronized (this) {
4618                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4619            }
4620        } finally {
4621            Binder.restoreCallingIdentity(origId);
4622        }
4623    }
4624
4625    final int startActivityInPackage(int uid, String callingPackage,
4626            Intent intent, String resolvedType, IBinder resultTo,
4627            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4628            IActivityContainer container, TaskRecord inTask) {
4629
4630        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4631                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4632
4633        // TODO: Switch to user app stacks here.
4634        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4635                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4636                null, null, null, bOptions, false, userId, container, inTask);
4637        return ret;
4638    }
4639
4640    @Override
4641    public final int startActivities(IApplicationThread caller, String callingPackage,
4642            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4643            int userId) {
4644        enforceNotIsolatedCaller("startActivities");
4645        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4646                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4647        // TODO: Switch to user app stacks here.
4648        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4649                resolvedTypes, resultTo, bOptions, userId);
4650        return ret;
4651    }
4652
4653    final int startActivitiesInPackage(int uid, String callingPackage,
4654            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4655            Bundle bOptions, int userId) {
4656
4657        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4658                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4659        // TODO: Switch to user app stacks here.
4660        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4661                resultTo, bOptions, userId);
4662        return ret;
4663    }
4664
4665    @Override
4666    public void reportActivityFullyDrawn(IBinder token) {
4667        synchronized (this) {
4668            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4669            if (r == null) {
4670                return;
4671            }
4672            r.reportFullyDrawnLocked();
4673        }
4674    }
4675
4676    @Override
4677    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4678        synchronized (this) {
4679            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4680            if (r == null) {
4681                return;
4682            }
4683            TaskRecord task = r.task;
4684            if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4685                // Fixed screen orientation isn't supported when activities aren't in full screen
4686                // mode.
4687                return;
4688            }
4689            final long origId = Binder.clearCallingIdentity();
4690            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4691            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4692                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4693            if (config != null) {
4694                r.frozenBeforeDestroy = true;
4695                if (!updateConfigurationLocked(config, r, false)) {
4696                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
4697                }
4698            }
4699            Binder.restoreCallingIdentity(origId);
4700        }
4701    }
4702
4703    @Override
4704    public int getRequestedOrientation(IBinder token) {
4705        synchronized (this) {
4706            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4707            if (r == null) {
4708                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4709            }
4710            return mWindowManager.getAppOrientation(r.appToken);
4711        }
4712    }
4713
4714    /**
4715     * This is the internal entry point for handling Activity.finish().
4716     *
4717     * @param token The Binder token referencing the Activity we want to finish.
4718     * @param resultCode Result code, if any, from this Activity.
4719     * @param resultData Result data (Intent), if any, from this Activity.
4720     * @param finishTask Whether to finish the task associated with this Activity.
4721     *
4722     * @return Returns true if the activity successfully finished, or false if it is still running.
4723     */
4724    @Override
4725    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4726            int finishTask) {
4727        // Refuse possible leaked file descriptors
4728        if (resultData != null && resultData.hasFileDescriptors() == true) {
4729            throw new IllegalArgumentException("File descriptors passed in Intent");
4730        }
4731
4732        synchronized(this) {
4733            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4734            if (r == null) {
4735                return true;
4736            }
4737            // Keep track of the root activity of the task before we finish it
4738            TaskRecord tr = r.task;
4739            ActivityRecord rootR = tr.getRootActivity();
4740            if (rootR == null) {
4741                Slog.w(TAG, "Finishing task with all activities already finished");
4742            }
4743            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4744            // finish.
4745            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4746                    mStackSupervisor.isLastLockedTask(tr)) {
4747                Slog.i(TAG, "Not finishing task in lock task mode");
4748                mStackSupervisor.showLockTaskToast();
4749                return false;
4750            }
4751            if (mController != null) {
4752                // Find the first activity that is not finishing.
4753                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4754                if (next != null) {
4755                    // ask watcher if this is allowed
4756                    boolean resumeOK = true;
4757                    try {
4758                        resumeOK = mController.activityResuming(next.packageName);
4759                    } catch (RemoteException e) {
4760                        mController = null;
4761                        Watchdog.getInstance().setActivityController(null);
4762                    }
4763
4764                    if (!resumeOK) {
4765                        Slog.i(TAG, "Not finishing activity because controller resumed");
4766                        return false;
4767                    }
4768                }
4769            }
4770            final long origId = Binder.clearCallingIdentity();
4771            try {
4772                boolean res;
4773                final boolean finishWithRootActivity =
4774                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4775                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4776                        || (finishWithRootActivity && r == rootR)) {
4777                    // If requested, remove the task that is associated to this activity only if it
4778                    // was the root activity in the task. The result code and data is ignored
4779                    // because we don't support returning them across task boundaries. Also, to
4780                    // keep backwards compatibility we remove the task from recents when finishing
4781                    // task with root activity.
4782                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4783                    if (!res) {
4784                        Slog.i(TAG, "Removing task failed to finish activity");
4785                    }
4786                } else {
4787                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4788                            resultData, "app-request", true);
4789                    if (!res) {
4790                        Slog.i(TAG, "Failed to finish by app-request");
4791                    }
4792                }
4793                return res;
4794            } finally {
4795                Binder.restoreCallingIdentity(origId);
4796            }
4797        }
4798    }
4799
4800    @Override
4801    public final void finishHeavyWeightApp() {
4802        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4803                != PackageManager.PERMISSION_GRANTED) {
4804            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4805                    + Binder.getCallingPid()
4806                    + ", uid=" + Binder.getCallingUid()
4807                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4808            Slog.w(TAG, msg);
4809            throw new SecurityException(msg);
4810        }
4811
4812        synchronized(this) {
4813            if (mHeavyWeightProcess == null) {
4814                return;
4815            }
4816
4817            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4818            for (int i = 0; i < activities.size(); i++) {
4819                ActivityRecord r = activities.get(i);
4820                if (!r.finishing && r.isInStackLocked()) {
4821                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4822                            null, "finish-heavy", true);
4823                }
4824            }
4825
4826            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4827                    mHeavyWeightProcess.userId, 0));
4828            mHeavyWeightProcess = null;
4829        }
4830    }
4831
4832    @Override
4833    public void crashApplication(int uid, int initialPid, String packageName,
4834            String message) {
4835        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4836                != PackageManager.PERMISSION_GRANTED) {
4837            String msg = "Permission Denial: crashApplication() from pid="
4838                    + Binder.getCallingPid()
4839                    + ", uid=" + Binder.getCallingUid()
4840                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4841            Slog.w(TAG, msg);
4842            throw new SecurityException(msg);
4843        }
4844
4845        synchronized(this) {
4846            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4847        }
4848    }
4849
4850    @Override
4851    public final void finishSubActivity(IBinder token, String resultWho,
4852            int requestCode) {
4853        synchronized(this) {
4854            final long origId = Binder.clearCallingIdentity();
4855            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4856            if (r != null) {
4857                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4858            }
4859            Binder.restoreCallingIdentity(origId);
4860        }
4861    }
4862
4863    @Override
4864    public boolean finishActivityAffinity(IBinder token) {
4865        synchronized(this) {
4866            final long origId = Binder.clearCallingIdentity();
4867            try {
4868                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4869                if (r == null) {
4870                    return false;
4871                }
4872
4873                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4874                // can finish.
4875                final TaskRecord task = r.task;
4876                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4877                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4878                    mStackSupervisor.showLockTaskToast();
4879                    return false;
4880                }
4881                return task.stack.finishActivityAffinityLocked(r);
4882            } finally {
4883                Binder.restoreCallingIdentity(origId);
4884            }
4885        }
4886    }
4887
4888    @Override
4889    public void finishVoiceTask(IVoiceInteractionSession session) {
4890        synchronized (this) {
4891            final long origId = Binder.clearCallingIdentity();
4892            try {
4893                // TODO: VI Consider treating local voice interactions and voice tasks
4894                // differently here
4895                mStackSupervisor.finishVoiceTask(session);
4896            } finally {
4897                Binder.restoreCallingIdentity(origId);
4898            }
4899        }
4900
4901    }
4902
4903    @Override
4904    public boolean releaseActivityInstance(IBinder token) {
4905        synchronized(this) {
4906            final long origId = Binder.clearCallingIdentity();
4907            try {
4908                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4909                if (r == null) {
4910                    return false;
4911                }
4912                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4913            } finally {
4914                Binder.restoreCallingIdentity(origId);
4915            }
4916        }
4917    }
4918
4919    @Override
4920    public void releaseSomeActivities(IApplicationThread appInt) {
4921        synchronized(this) {
4922            final long origId = Binder.clearCallingIdentity();
4923            try {
4924                ProcessRecord app = getRecordForAppLocked(appInt);
4925                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4926            } finally {
4927                Binder.restoreCallingIdentity(origId);
4928            }
4929        }
4930    }
4931
4932    @Override
4933    public boolean willActivityBeVisible(IBinder token) {
4934        synchronized(this) {
4935            ActivityStack stack = ActivityRecord.getStackLocked(token);
4936            if (stack != null) {
4937                return stack.willActivityBeVisibleLocked(token);
4938            }
4939            return false;
4940        }
4941    }
4942
4943    @Override
4944    public void overridePendingTransition(IBinder token, String packageName,
4945            int enterAnim, int exitAnim) {
4946        synchronized(this) {
4947            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4948            if (self == null) {
4949                return;
4950            }
4951
4952            final long origId = Binder.clearCallingIdentity();
4953
4954            if (self.state == ActivityState.RESUMED
4955                    || self.state == ActivityState.PAUSING) {
4956                mWindowManager.overridePendingAppTransition(packageName,
4957                        enterAnim, exitAnim, null);
4958            }
4959
4960            Binder.restoreCallingIdentity(origId);
4961        }
4962    }
4963
4964    /**
4965     * Main function for removing an existing process from the activity manager
4966     * as a result of that process going away.  Clears out all connections
4967     * to the process.
4968     */
4969    private final void handleAppDiedLocked(ProcessRecord app,
4970            boolean restarting, boolean allowRestart) {
4971        int pid = app.pid;
4972        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4973        if (!kept && !restarting) {
4974            removeLruProcessLocked(app);
4975            if (pid > 0) {
4976                ProcessList.remove(pid);
4977            }
4978        }
4979
4980        if (mProfileProc == app) {
4981            clearProfilerLocked();
4982        }
4983
4984        // Remove this application's activities from active lists.
4985        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4986
4987        app.activities.clear();
4988
4989        if (app.instrumentationClass != null) {
4990            Slog.w(TAG, "Crash of app " + app.processName
4991                  + " running instrumentation " + app.instrumentationClass);
4992            Bundle info = new Bundle();
4993            info.putString("shortMsg", "Process crashed.");
4994            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4995        }
4996
4997        if (!restarting && hasVisibleActivities
4998                && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
4999            // If there was nothing to resume, and we are not already restarting this process, but
5000            // there is a visible activity that is hosted by the process...  then make sure all
5001            // visible activities are running, taking care of restarting this process.
5002            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5003        }
5004    }
5005
5006    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5007        IBinder threadBinder = thread.asBinder();
5008        // Find the application record.
5009        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5010            ProcessRecord rec = mLruProcesses.get(i);
5011            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5012                return i;
5013            }
5014        }
5015        return -1;
5016    }
5017
5018    final ProcessRecord getRecordForAppLocked(
5019            IApplicationThread thread) {
5020        if (thread == null) {
5021            return null;
5022        }
5023
5024        int appIndex = getLRURecordIndexForAppLocked(thread);
5025        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
5026    }
5027
5028    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5029        // If there are no longer any background processes running,
5030        // and the app that died was not running instrumentation,
5031        // then tell everyone we are now low on memory.
5032        boolean haveBg = false;
5033        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5034            ProcessRecord rec = mLruProcesses.get(i);
5035            if (rec.thread != null
5036                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5037                haveBg = true;
5038                break;
5039            }
5040        }
5041
5042        if (!haveBg) {
5043            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5044            if (doReport) {
5045                long now = SystemClock.uptimeMillis();
5046                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5047                    doReport = false;
5048                } else {
5049                    mLastMemUsageReportTime = now;
5050                }
5051            }
5052            final ArrayList<ProcessMemInfo> memInfos
5053                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5054            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5055            long now = SystemClock.uptimeMillis();
5056            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5057                ProcessRecord rec = mLruProcesses.get(i);
5058                if (rec == dyingProc || rec.thread == null) {
5059                    continue;
5060                }
5061                if (doReport) {
5062                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5063                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5064                }
5065                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5066                    // The low memory report is overriding any current
5067                    // state for a GC request.  Make sure to do
5068                    // heavy/important/visible/foreground processes first.
5069                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5070                        rec.lastRequestedGc = 0;
5071                    } else {
5072                        rec.lastRequestedGc = rec.lastLowMemory;
5073                    }
5074                    rec.reportLowMemory = true;
5075                    rec.lastLowMemory = now;
5076                    mProcessesToGc.remove(rec);
5077                    addProcessToGcListLocked(rec);
5078                }
5079            }
5080            if (doReport) {
5081                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5082                mHandler.sendMessage(msg);
5083            }
5084            scheduleAppGcsLocked();
5085        }
5086    }
5087
5088    final void appDiedLocked(ProcessRecord app) {
5089       appDiedLocked(app, app.pid, app.thread, false);
5090    }
5091
5092    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5093            boolean fromBinderDied) {
5094        // First check if this ProcessRecord is actually active for the pid.
5095        synchronized (mPidsSelfLocked) {
5096            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5097            if (curProc != app) {
5098                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5099                return;
5100            }
5101        }
5102
5103        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5104        synchronized (stats) {
5105            stats.noteProcessDiedLocked(app.info.uid, pid);
5106        }
5107
5108        if (!app.killed) {
5109            if (!fromBinderDied) {
5110                Process.killProcessQuiet(pid);
5111            }
5112            killProcessGroup(app.uid, pid);
5113            app.killed = true;
5114        }
5115
5116        // Clean up already done if the process has been re-started.
5117        if (app.pid == pid && app.thread != null &&
5118                app.thread.asBinder() == thread.asBinder()) {
5119            boolean doLowMem = app.instrumentationClass == null;
5120            boolean doOomAdj = doLowMem;
5121            if (!app.killedByAm) {
5122                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5123                        + ") has died");
5124                mAllowLowerMemLevel = true;
5125            } else {
5126                // Note that we always want to do oom adj to update our state with the
5127                // new number of procs.
5128                mAllowLowerMemLevel = false;
5129                doLowMem = false;
5130            }
5131            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5132            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5133                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5134            handleAppDiedLocked(app, false, true);
5135
5136            if (doOomAdj) {
5137                updateOomAdjLocked();
5138            }
5139            if (doLowMem) {
5140                doLowMemReportIfNeededLocked(app);
5141            }
5142        } else if (app.pid != pid) {
5143            // A new process has already been started.
5144            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5145                    + ") has died and restarted (pid " + app.pid + ").");
5146            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5147        } else if (DEBUG_PROCESSES) {
5148            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5149                    + thread.asBinder());
5150        }
5151    }
5152
5153    /**
5154     * If a stack trace dump file is configured, dump process stack traces.
5155     * @param clearTraces causes the dump file to be erased prior to the new
5156     *    traces being written, if true; when false, the new traces will be
5157     *    appended to any existing file content.
5158     * @param firstPids of dalvik VM processes to dump stack traces for first
5159     * @param lastPids of dalvik VM processes to dump stack traces for last
5160     * @param nativeProcs optional list of native process names to dump stack crawls
5161     * @return file containing stack traces, or null if no dump file is configured
5162     */
5163    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5164            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5165        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5166        if (tracesPath == null || tracesPath.length() == 0) {
5167            return null;
5168        }
5169
5170        File tracesFile = new File(tracesPath);
5171        try {
5172            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5173            tracesFile.createNewFile();
5174            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5175        } catch (IOException e) {
5176            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5177            return null;
5178        }
5179
5180        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5181        return tracesFile;
5182    }
5183
5184    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5185            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5186        // Use a FileObserver to detect when traces finish writing.
5187        // The order of traces is considered important to maintain for legibility.
5188        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5189            @Override
5190            public synchronized void onEvent(int event, String path) { notify(); }
5191        };
5192
5193        try {
5194            observer.startWatching();
5195
5196            // First collect all of the stacks of the most important pids.
5197            if (firstPids != null) {
5198                try {
5199                    int num = firstPids.size();
5200                    for (int i = 0; i < num; i++) {
5201                        synchronized (observer) {
5202                            if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5203                                    + firstPids.get(i));
5204                            final long sime = SystemClock.elapsedRealtime();
5205                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5206                            observer.wait(1000);  // Wait for write-close, give up after 1 sec
5207                            if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5208                                    + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5209                        }
5210                    }
5211                } catch (InterruptedException e) {
5212                    Slog.wtf(TAG, e);
5213                }
5214            }
5215
5216            // Next collect the stacks of the native pids
5217            if (nativeProcs != null) {
5218                int[] pids = Process.getPidsForCommands(nativeProcs);
5219                if (pids != null) {
5220                    for (int pid : pids) {
5221                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5222                        final long sime = SystemClock.elapsedRealtime();
5223                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5224                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5225                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5226                    }
5227                }
5228            }
5229
5230            // Lastly, measure CPU usage.
5231            if (processCpuTracker != null) {
5232                processCpuTracker.init();
5233                System.gc();
5234                processCpuTracker.update();
5235                try {
5236                    synchronized (processCpuTracker) {
5237                        processCpuTracker.wait(500); // measure over 1/2 second.
5238                    }
5239                } catch (InterruptedException e) {
5240                }
5241                processCpuTracker.update();
5242
5243                // We'll take the stack crawls of just the top apps using CPU.
5244                final int N = processCpuTracker.countWorkingStats();
5245                int numProcs = 0;
5246                for (int i=0; i<N && numProcs<5; i++) {
5247                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5248                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5249                        numProcs++;
5250                        try {
5251                            synchronized (observer) {
5252                                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5253                                        + stats.pid);
5254                                final long stime = SystemClock.elapsedRealtime();
5255                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5256                                observer.wait(1000);  // Wait for write-close, give up after 1 sec
5257                                if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5258                                        + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5259                            }
5260                        } catch (InterruptedException e) {
5261                            Slog.wtf(TAG, e);
5262                        }
5263                    } else if (DEBUG_ANR) {
5264                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5265                                + stats.pid);
5266                    }
5267                }
5268            }
5269        } finally {
5270            observer.stopWatching();
5271        }
5272    }
5273
5274    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5275        if (true || IS_USER_BUILD) {
5276            return;
5277        }
5278        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5279        if (tracesPath == null || tracesPath.length() == 0) {
5280            return;
5281        }
5282
5283        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5284        StrictMode.allowThreadDiskWrites();
5285        try {
5286            final File tracesFile = new File(tracesPath);
5287            final File tracesDir = tracesFile.getParentFile();
5288            final File tracesTmp = new File(tracesDir, "__tmp__");
5289            try {
5290                if (tracesFile.exists()) {
5291                    tracesTmp.delete();
5292                    tracesFile.renameTo(tracesTmp);
5293                }
5294                StringBuilder sb = new StringBuilder();
5295                Time tobj = new Time();
5296                tobj.set(System.currentTimeMillis());
5297                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5298                sb.append(": ");
5299                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5300                sb.append(" since ");
5301                sb.append(msg);
5302                FileOutputStream fos = new FileOutputStream(tracesFile);
5303                fos.write(sb.toString().getBytes());
5304                if (app == null) {
5305                    fos.write("\n*** No application process!".getBytes());
5306                }
5307                fos.close();
5308                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5309            } catch (IOException e) {
5310                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5311                return;
5312            }
5313
5314            if (app != null) {
5315                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5316                firstPids.add(app.pid);
5317                dumpStackTraces(tracesPath, firstPids, null, null, null);
5318            }
5319
5320            File lastTracesFile = null;
5321            File curTracesFile = null;
5322            for (int i=9; i>=0; i--) {
5323                String name = String.format(Locale.US, "slow%02d.txt", i);
5324                curTracesFile = new File(tracesDir, name);
5325                if (curTracesFile.exists()) {
5326                    if (lastTracesFile != null) {
5327                        curTracesFile.renameTo(lastTracesFile);
5328                    } else {
5329                        curTracesFile.delete();
5330                    }
5331                }
5332                lastTracesFile = curTracesFile;
5333            }
5334            tracesFile.renameTo(curTracesFile);
5335            if (tracesTmp.exists()) {
5336                tracesTmp.renameTo(tracesFile);
5337            }
5338        } finally {
5339            StrictMode.setThreadPolicy(oldPolicy);
5340        }
5341    }
5342
5343    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5344        if (!mLaunchWarningShown) {
5345            mLaunchWarningShown = true;
5346            mUiHandler.post(new Runnable() {
5347                @Override
5348                public void run() {
5349                    synchronized (ActivityManagerService.this) {
5350                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5351                        d.show();
5352                        mUiHandler.postDelayed(new Runnable() {
5353                            @Override
5354                            public void run() {
5355                                synchronized (ActivityManagerService.this) {
5356                                    d.dismiss();
5357                                    mLaunchWarningShown = false;
5358                                }
5359                            }
5360                        }, 4000);
5361                    }
5362                }
5363            });
5364        }
5365    }
5366
5367    @Override
5368    public boolean clearApplicationUserData(final String packageName,
5369            final IPackageDataObserver observer, int userId) {
5370        enforceNotIsolatedCaller("clearApplicationUserData");
5371        int uid = Binder.getCallingUid();
5372        int pid = Binder.getCallingPid();
5373        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5374                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5375
5376        final DevicePolicyManagerInternal dpmi = LocalServices
5377                .getService(DevicePolicyManagerInternal.class);
5378        if (dpmi != null && dpmi.hasDeviceOwnerOrProfileOwner(packageName, userId)) {
5379            throw new SecurityException("Cannot clear data for a device owner or a profile owner");
5380        }
5381
5382        long callingId = Binder.clearCallingIdentity();
5383        try {
5384            IPackageManager pm = AppGlobals.getPackageManager();
5385            int pkgUid = -1;
5386            synchronized(this) {
5387                try {
5388                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5389                } catch (RemoteException e) {
5390                }
5391                if (pkgUid == -1) {
5392                    Slog.w(TAG, "Invalid packageName: " + packageName);
5393                    if (observer != null) {
5394                        try {
5395                            observer.onRemoveCompleted(packageName, false);
5396                        } catch (RemoteException e) {
5397                            Slog.i(TAG, "Observer no longer exists.");
5398                        }
5399                    }
5400                    return false;
5401                }
5402                if (uid == pkgUid || checkComponentPermission(
5403                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5404                        pid, uid, -1, true)
5405                        == PackageManager.PERMISSION_GRANTED) {
5406                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5407                } else {
5408                    throw new SecurityException("PID " + pid + " does not have permission "
5409                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5410                                    + " of package " + packageName);
5411                }
5412
5413                // Remove all tasks match the cleared application package and user
5414                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5415                    final TaskRecord tr = mRecentTasks.get(i);
5416                    final String taskPackageName =
5417                            tr.getBaseIntent().getComponent().getPackageName();
5418                    if (tr.userId != userId) continue;
5419                    if (!taskPackageName.equals(packageName)) continue;
5420                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5421                }
5422            }
5423
5424            try {
5425                // Clear application user data
5426                pm.clearApplicationUserData(packageName, observer, userId);
5427
5428                synchronized(this) {
5429                    // Remove all permissions granted from/to this package
5430                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5431                }
5432
5433                // Remove all zen rules created by this package; revoke it's zen access.
5434                INotificationManager inm = NotificationManager.getService();
5435                inm.removeAutomaticZenRules(packageName);
5436                inm.setNotificationPolicyAccessGranted(packageName, false);
5437
5438                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5439                        Uri.fromParts("package", packageName, null));
5440                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5441                intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUid));
5442                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5443                        null, null, 0, null, null, null, null, false, false, userId);
5444            } catch (RemoteException e) {
5445            }
5446        } finally {
5447            Binder.restoreCallingIdentity(callingId);
5448        }
5449        return true;
5450    }
5451
5452    @Override
5453    public void killBackgroundProcesses(final String packageName, int userId) {
5454        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5455                != PackageManager.PERMISSION_GRANTED &&
5456                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5457                        != PackageManager.PERMISSION_GRANTED) {
5458            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5459                    + Binder.getCallingPid()
5460                    + ", uid=" + Binder.getCallingUid()
5461                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5462            Slog.w(TAG, msg);
5463            throw new SecurityException(msg);
5464        }
5465
5466        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5467                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5468        long callingId = Binder.clearCallingIdentity();
5469        try {
5470            IPackageManager pm = AppGlobals.getPackageManager();
5471            synchronized(this) {
5472                int appId = -1;
5473                try {
5474                    appId = UserHandle.getAppId(
5475                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5476                } catch (RemoteException e) {
5477                }
5478                if (appId == -1) {
5479                    Slog.w(TAG, "Invalid packageName: " + packageName);
5480                    return;
5481                }
5482                killPackageProcessesLocked(packageName, appId, userId,
5483                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5484            }
5485        } finally {
5486            Binder.restoreCallingIdentity(callingId);
5487        }
5488    }
5489
5490    @Override
5491    public void killAllBackgroundProcesses() {
5492        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5493                != PackageManager.PERMISSION_GRANTED) {
5494            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5495                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5496                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5497            Slog.w(TAG, msg);
5498            throw new SecurityException(msg);
5499        }
5500
5501        final long callingId = Binder.clearCallingIdentity();
5502        try {
5503            synchronized (this) {
5504                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5505                final int NP = mProcessNames.getMap().size();
5506                for (int ip = 0; ip < NP; ip++) {
5507                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5508                    final int NA = apps.size();
5509                    for (int ia = 0; ia < NA; ia++) {
5510                        final ProcessRecord app = apps.valueAt(ia);
5511                        if (app.persistent) {
5512                            // We don't kill persistent processes.
5513                            continue;
5514                        }
5515                        if (app.removed) {
5516                            procs.add(app);
5517                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5518                            app.removed = true;
5519                            procs.add(app);
5520                        }
5521                    }
5522                }
5523
5524                final int N = procs.size();
5525                for (int i = 0; i < N; i++) {
5526                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5527                }
5528
5529                mAllowLowerMemLevel = true;
5530
5531                updateOomAdjLocked();
5532                doLowMemReportIfNeededLocked(null);
5533            }
5534        } finally {
5535            Binder.restoreCallingIdentity(callingId);
5536        }
5537    }
5538
5539    /**
5540     * Kills all background processes, except those matching any of the
5541     * specified properties.
5542     *
5543     * @param minTargetSdk the target SDK version at or above which to preserve
5544     *                     processes, or {@code -1} to ignore the target SDK
5545     * @param maxProcState the process state at or below which to preserve
5546     *                     processes, or {@code -1} to ignore the process state
5547     */
5548    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5549        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5550                != PackageManager.PERMISSION_GRANTED) {
5551            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5552                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5553                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5554            Slog.w(TAG, msg);
5555            throw new SecurityException(msg);
5556        }
5557
5558        final long callingId = Binder.clearCallingIdentity();
5559        try {
5560            synchronized (this) {
5561                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5562                final int NP = mProcessNames.getMap().size();
5563                for (int ip = 0; ip < NP; ip++) {
5564                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5565                    final int NA = apps.size();
5566                    for (int ia = 0; ia < NA; ia++) {
5567                        final ProcessRecord app = apps.valueAt(ia);
5568                        if (app.removed) {
5569                            procs.add(app);
5570                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5571                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5572                            app.removed = true;
5573                            procs.add(app);
5574                        }
5575                    }
5576                }
5577
5578                final int N = procs.size();
5579                for (int i = 0; i < N; i++) {
5580                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5581                }
5582            }
5583        } finally {
5584            Binder.restoreCallingIdentity(callingId);
5585        }
5586    }
5587
5588    @Override
5589    public void forceStopPackage(final String packageName, int userId) {
5590        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5591                != PackageManager.PERMISSION_GRANTED) {
5592            String msg = "Permission Denial: forceStopPackage() from pid="
5593                    + Binder.getCallingPid()
5594                    + ", uid=" + Binder.getCallingUid()
5595                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5596            Slog.w(TAG, msg);
5597            throw new SecurityException(msg);
5598        }
5599        final int callingPid = Binder.getCallingPid();
5600        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5601                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5602        long callingId = Binder.clearCallingIdentity();
5603        try {
5604            IPackageManager pm = AppGlobals.getPackageManager();
5605            synchronized(this) {
5606                int[] users = userId == UserHandle.USER_ALL
5607                        ? mUserController.getUsers() : new int[] { userId };
5608                for (int user : users) {
5609                    int pkgUid = -1;
5610                    try {
5611                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5612                                user);
5613                    } catch (RemoteException e) {
5614                    }
5615                    if (pkgUid == -1) {
5616                        Slog.w(TAG, "Invalid packageName: " + packageName);
5617                        continue;
5618                    }
5619                    try {
5620                        pm.setPackageStoppedState(packageName, true, user);
5621                    } catch (RemoteException e) {
5622                    } catch (IllegalArgumentException e) {
5623                        Slog.w(TAG, "Failed trying to unstop package "
5624                                + packageName + ": " + e);
5625                    }
5626                    if (mUserController.isUserRunningLocked(user, 0)) {
5627                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5628                    }
5629                }
5630            }
5631        } finally {
5632            Binder.restoreCallingIdentity(callingId);
5633        }
5634    }
5635
5636    @Override
5637    public void addPackageDependency(String packageName) {
5638        synchronized (this) {
5639            int callingPid = Binder.getCallingPid();
5640            if (callingPid == Process.myPid()) {
5641                //  Yeah, um, no.
5642                return;
5643            }
5644            ProcessRecord proc;
5645            synchronized (mPidsSelfLocked) {
5646                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5647            }
5648            if (proc != null) {
5649                if (proc.pkgDeps == null) {
5650                    proc.pkgDeps = new ArraySet<String>(1);
5651                }
5652                proc.pkgDeps.add(packageName);
5653            }
5654        }
5655    }
5656
5657    /*
5658     * The pkg name and app id have to be specified.
5659     */
5660    @Override
5661    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5662        if (pkg == null) {
5663            return;
5664        }
5665        // Make sure the uid is valid.
5666        if (appid < 0) {
5667            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5668            return;
5669        }
5670        int callerUid = Binder.getCallingUid();
5671        // Only the system server can kill an application
5672        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5673            // Post an aysnc message to kill the application
5674            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5675            msg.arg1 = appid;
5676            msg.arg2 = 0;
5677            Bundle bundle = new Bundle();
5678            bundle.putString("pkg", pkg);
5679            bundle.putString("reason", reason);
5680            msg.obj = bundle;
5681            mHandler.sendMessage(msg);
5682        } else {
5683            throw new SecurityException(callerUid + " cannot kill pkg: " +
5684                    pkg);
5685        }
5686    }
5687
5688    @Override
5689    public void closeSystemDialogs(String reason) {
5690        enforceNotIsolatedCaller("closeSystemDialogs");
5691
5692        final int pid = Binder.getCallingPid();
5693        final int uid = Binder.getCallingUid();
5694        final long origId = Binder.clearCallingIdentity();
5695        try {
5696            synchronized (this) {
5697                // Only allow this from foreground processes, so that background
5698                // applications can't abuse it to prevent system UI from being shown.
5699                if (uid >= Process.FIRST_APPLICATION_UID) {
5700                    ProcessRecord proc;
5701                    synchronized (mPidsSelfLocked) {
5702                        proc = mPidsSelfLocked.get(pid);
5703                    }
5704                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5705                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5706                                + " from background process " + proc);
5707                        return;
5708                    }
5709                }
5710                closeSystemDialogsLocked(reason);
5711            }
5712        } finally {
5713            Binder.restoreCallingIdentity(origId);
5714        }
5715    }
5716
5717    void closeSystemDialogsLocked(String reason) {
5718        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5719        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5720                | Intent.FLAG_RECEIVER_FOREGROUND);
5721        if (reason != null) {
5722            intent.putExtra("reason", reason);
5723        }
5724        mWindowManager.closeSystemDialogs(reason);
5725
5726        mStackSupervisor.closeSystemDialogsLocked();
5727
5728        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5729                AppOpsManager.OP_NONE, null, false, false,
5730                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5731    }
5732
5733    @Override
5734    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5735        enforceNotIsolatedCaller("getProcessMemoryInfo");
5736        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5737        for (int i=pids.length-1; i>=0; i--) {
5738            ProcessRecord proc;
5739            int oomAdj;
5740            synchronized (this) {
5741                synchronized (mPidsSelfLocked) {
5742                    proc = mPidsSelfLocked.get(pids[i]);
5743                    oomAdj = proc != null ? proc.setAdj : 0;
5744                }
5745            }
5746            infos[i] = new Debug.MemoryInfo();
5747            Debug.getMemoryInfo(pids[i], infos[i]);
5748            if (proc != null) {
5749                synchronized (this) {
5750                    if (proc.thread != null && proc.setAdj == oomAdj) {
5751                        // Record this for posterity if the process has been stable.
5752                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5753                                infos[i].getTotalUss(), false, proc.pkgList);
5754                    }
5755                }
5756            }
5757        }
5758        return infos;
5759    }
5760
5761    @Override
5762    public long[] getProcessPss(int[] pids) {
5763        enforceNotIsolatedCaller("getProcessPss");
5764        long[] pss = new long[pids.length];
5765        for (int i=pids.length-1; i>=0; i--) {
5766            ProcessRecord proc;
5767            int oomAdj;
5768            synchronized (this) {
5769                synchronized (mPidsSelfLocked) {
5770                    proc = mPidsSelfLocked.get(pids[i]);
5771                    oomAdj = proc != null ? proc.setAdj : 0;
5772                }
5773            }
5774            long[] tmpUss = new long[1];
5775            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5776            if (proc != null) {
5777                synchronized (this) {
5778                    if (proc.thread != null && proc.setAdj == oomAdj) {
5779                        // Record this for posterity if the process has been stable.
5780                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5781                    }
5782                }
5783            }
5784        }
5785        return pss;
5786    }
5787
5788    @Override
5789    public void killApplicationProcess(String processName, int uid) {
5790        if (processName == null) {
5791            return;
5792        }
5793
5794        int callerUid = Binder.getCallingUid();
5795        // Only the system server can kill an application
5796        if (callerUid == Process.SYSTEM_UID) {
5797            synchronized (this) {
5798                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5799                if (app != null && app.thread != null) {
5800                    try {
5801                        app.thread.scheduleSuicide();
5802                    } catch (RemoteException e) {
5803                        // If the other end already died, then our work here is done.
5804                    }
5805                } else {
5806                    Slog.w(TAG, "Process/uid not found attempting kill of "
5807                            + processName + " / " + uid);
5808                }
5809            }
5810        } else {
5811            throw new SecurityException(callerUid + " cannot kill app process: " +
5812                    processName);
5813        }
5814    }
5815
5816    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5817        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5818                false, true, false, false, UserHandle.getUserId(uid), reason);
5819        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5820                Uri.fromParts("package", packageName, null));
5821        if (!mProcessesReady) {
5822            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5823                    | Intent.FLAG_RECEIVER_FOREGROUND);
5824        }
5825        intent.putExtra(Intent.EXTRA_UID, uid);
5826        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5827        broadcastIntentLocked(null, null, intent,
5828                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5829                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5830    }
5831
5832
5833    private final boolean killPackageProcessesLocked(String packageName, int appId,
5834            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5835            boolean doit, boolean evenPersistent, String reason) {
5836        ArrayList<ProcessRecord> procs = new ArrayList<>();
5837
5838        // Remove all processes this package may have touched: all with the
5839        // same UID (except for the system or root user), and all whose name
5840        // matches the package name.
5841        final int NP = mProcessNames.getMap().size();
5842        for (int ip=0; ip<NP; ip++) {
5843            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5844            final int NA = apps.size();
5845            for (int ia=0; ia<NA; ia++) {
5846                ProcessRecord app = apps.valueAt(ia);
5847                if (app.persistent && !evenPersistent) {
5848                    // we don't kill persistent processes
5849                    continue;
5850                }
5851                if (app.removed) {
5852                    if (doit) {
5853                        procs.add(app);
5854                    }
5855                    continue;
5856                }
5857
5858                // Skip process if it doesn't meet our oom adj requirement.
5859                if (app.setAdj < minOomAdj) {
5860                    continue;
5861                }
5862
5863                // If no package is specified, we call all processes under the
5864                // give user id.
5865                if (packageName == null) {
5866                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5867                        continue;
5868                    }
5869                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5870                        continue;
5871                    }
5872                // Package has been specified, we want to hit all processes
5873                // that match it.  We need to qualify this by the processes
5874                // that are running under the specified app and user ID.
5875                } else {
5876                    final boolean isDep = app.pkgDeps != null
5877                            && app.pkgDeps.contains(packageName);
5878                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5879                        continue;
5880                    }
5881                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5882                        continue;
5883                    }
5884                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5885                        continue;
5886                    }
5887                }
5888
5889                // Process has passed all conditions, kill it!
5890                if (!doit) {
5891                    return true;
5892                }
5893                app.removed = true;
5894                procs.add(app);
5895            }
5896        }
5897
5898        int N = procs.size();
5899        for (int i=0; i<N; i++) {
5900            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5901        }
5902        updateOomAdjLocked();
5903        return N > 0;
5904    }
5905
5906    private void cleanupDisabledPackageComponentsLocked(
5907            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5908
5909        Set<String> disabledClasses = null;
5910        boolean packageDisabled = false;
5911        IPackageManager pm = AppGlobals.getPackageManager();
5912
5913        if (changedClasses == null) {
5914            // Nothing changed...
5915            return;
5916        }
5917
5918        // Determine enable/disable state of the package and its components.
5919        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5920        for (int i = changedClasses.length - 1; i >= 0; i--) {
5921            final String changedClass = changedClasses[i];
5922
5923            if (changedClass.equals(packageName)) {
5924                try {
5925                    // Entire package setting changed
5926                    enabled = pm.getApplicationEnabledSetting(packageName,
5927                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5928                } catch (Exception e) {
5929                    // No such package/component; probably racing with uninstall.  In any
5930                    // event it means we have nothing further to do here.
5931                    return;
5932                }
5933                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5934                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5935                if (packageDisabled) {
5936                    // Entire package is disabled.
5937                    // No need to continue to check component states.
5938                    disabledClasses = null;
5939                    break;
5940                }
5941            } else {
5942                try {
5943                    enabled = pm.getComponentEnabledSetting(
5944                            new ComponentName(packageName, changedClass),
5945                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5946                } catch (Exception e) {
5947                    // As above, probably racing with uninstall.
5948                    return;
5949                }
5950                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5951                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5952                    if (disabledClasses == null) {
5953                        disabledClasses = new ArraySet<>(changedClasses.length);
5954                    }
5955                    disabledClasses.add(changedClass);
5956                }
5957            }
5958        }
5959
5960        if (!packageDisabled && disabledClasses == null) {
5961            // Nothing to do here...
5962            return;
5963        }
5964
5965        // Clean-up disabled activities.
5966        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5967                packageName, disabledClasses, true, false, userId) && mBooted) {
5968            mStackSupervisor.resumeFocusedStackTopActivityLocked();
5969            mStackSupervisor.scheduleIdleLocked();
5970        }
5971
5972        // Clean-up disabled tasks
5973        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5974
5975        // Clean-up disabled services.
5976        mServices.bringDownDisabledPackageServicesLocked(
5977                packageName, disabledClasses, userId, false, killProcess, true);
5978
5979        // Clean-up disabled providers.
5980        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5981        mProviderMap.collectPackageProvidersLocked(
5982                packageName, disabledClasses, true, false, userId, providers);
5983        for (int i = providers.size() - 1; i >= 0; i--) {
5984            removeDyingProviderLocked(null, providers.get(i), true);
5985        }
5986
5987        // Clean-up disabled broadcast receivers.
5988        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5989            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5990                    packageName, disabledClasses, userId, true);
5991        }
5992
5993    }
5994
5995    final boolean clearBroadcastQueueForUserLocked(int userId) {
5996        boolean didSomething = false;
5997        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5998            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5999                    null, null, userId, true);
6000        }
6001        return didSomething;
6002    }
6003
6004    final boolean forceStopPackageLocked(String packageName, int appId,
6005            boolean callerWillRestart, boolean purgeCache, boolean doit,
6006            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6007        int i;
6008
6009        if (userId == UserHandle.USER_ALL && packageName == null) {
6010            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6011        }
6012
6013        if (appId < 0 && packageName != null) {
6014            try {
6015                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6016                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
6017            } catch (RemoteException e) {
6018            }
6019        }
6020
6021        if (doit) {
6022            if (packageName != null) {
6023                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6024                        + " user=" + userId + ": " + reason);
6025            } else {
6026                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6027            }
6028
6029            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6030        }
6031
6032        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6033                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6034                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6035
6036        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6037                packageName, null, doit, evenPersistent, userId)) {
6038            if (!doit) {
6039                return true;
6040            }
6041            didSomething = true;
6042        }
6043
6044        if (mServices.bringDownDisabledPackageServicesLocked(
6045                packageName, null, userId, evenPersistent, true, doit)) {
6046            if (!doit) {
6047                return true;
6048            }
6049            didSomething = true;
6050        }
6051
6052        if (packageName == null) {
6053            // Remove all sticky broadcasts from this user.
6054            mStickyBroadcasts.remove(userId);
6055        }
6056
6057        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6058        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6059                userId, providers)) {
6060            if (!doit) {
6061                return true;
6062            }
6063            didSomething = true;
6064        }
6065        for (i = providers.size() - 1; i >= 0; i--) {
6066            removeDyingProviderLocked(null, providers.get(i), true);
6067        }
6068
6069        // Remove transient permissions granted from/to this package/user
6070        removeUriPermissionsForPackageLocked(packageName, userId, false);
6071
6072        if (doit) {
6073            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6074                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6075                        packageName, null, userId, doit);
6076            }
6077        }
6078
6079        if (packageName == null || uninstalling) {
6080            // Remove pending intents.  For now we only do this when force
6081            // stopping users, because we have some problems when doing this
6082            // for packages -- app widgets are not currently cleaned up for
6083            // such packages, so they can be left with bad pending intents.
6084            if (mIntentSenderRecords.size() > 0) {
6085                Iterator<WeakReference<PendingIntentRecord>> it
6086                        = mIntentSenderRecords.values().iterator();
6087                while (it.hasNext()) {
6088                    WeakReference<PendingIntentRecord> wpir = it.next();
6089                    if (wpir == null) {
6090                        it.remove();
6091                        continue;
6092                    }
6093                    PendingIntentRecord pir = wpir.get();
6094                    if (pir == null) {
6095                        it.remove();
6096                        continue;
6097                    }
6098                    if (packageName == null) {
6099                        // Stopping user, remove all objects for the user.
6100                        if (pir.key.userId != userId) {
6101                            // Not the same user, skip it.
6102                            continue;
6103                        }
6104                    } else {
6105                        if (UserHandle.getAppId(pir.uid) != appId) {
6106                            // Different app id, skip it.
6107                            continue;
6108                        }
6109                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6110                            // Different user, skip it.
6111                            continue;
6112                        }
6113                        if (!pir.key.packageName.equals(packageName)) {
6114                            // Different package, skip it.
6115                            continue;
6116                        }
6117                    }
6118                    if (!doit) {
6119                        return true;
6120                    }
6121                    didSomething = true;
6122                    it.remove();
6123                    pir.canceled = true;
6124                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6125                        pir.key.activity.pendingResults.remove(pir.ref);
6126                    }
6127                }
6128            }
6129        }
6130
6131        if (doit) {
6132            if (purgeCache && packageName != null) {
6133                AttributeCache ac = AttributeCache.instance();
6134                if (ac != null) {
6135                    ac.removePackage(packageName);
6136                }
6137            }
6138            if (mBooted) {
6139                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6140                mStackSupervisor.scheduleIdleLocked();
6141            }
6142        }
6143
6144        return didSomething;
6145    }
6146
6147    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6148        ProcessRecord old = mProcessNames.remove(name, uid);
6149        if (old != null) {
6150            old.uidRecord.numProcs--;
6151            if (old.uidRecord.numProcs == 0) {
6152                // No more processes using this uid, tell clients it is gone.
6153                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6154                        "No more processes in " + old.uidRecord);
6155                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6156                mActiveUids.remove(uid);
6157                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6158            }
6159            old.uidRecord = null;
6160        }
6161        mIsolatedProcesses.remove(uid);
6162        return old;
6163    }
6164
6165    private final void addProcessNameLocked(ProcessRecord proc) {
6166        // We shouldn't already have a process under this name, but just in case we
6167        // need to clean up whatever may be there now.
6168        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6169        if (old == proc && proc.persistent) {
6170            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6171            Slog.w(TAG, "Re-adding persistent process " + proc);
6172        } else if (old != null) {
6173            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6174        }
6175        UidRecord uidRec = mActiveUids.get(proc.uid);
6176        if (uidRec == null) {
6177            uidRec = new UidRecord(proc.uid);
6178            // This is the first appearance of the uid, report it now!
6179            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6180                    "Creating new process uid: " + uidRec);
6181            mActiveUids.put(proc.uid, uidRec);
6182            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6183            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6184        }
6185        proc.uidRecord = uidRec;
6186        uidRec.numProcs++;
6187        mProcessNames.put(proc.processName, proc.uid, proc);
6188        if (proc.isolated) {
6189            mIsolatedProcesses.put(proc.uid, proc);
6190        }
6191    }
6192
6193    boolean removeProcessLocked(ProcessRecord app,
6194            boolean callerWillRestart, boolean allowRestart, String reason) {
6195        final String name = app.processName;
6196        final int uid = app.uid;
6197        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6198            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6199
6200        ProcessRecord old = mProcessNames.get(name, uid);
6201        if (old != app) {
6202            // This process is no longer active, so nothing to do.
6203            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6204            return false;
6205        }
6206        removeProcessNameLocked(name, uid);
6207        if (mHeavyWeightProcess == app) {
6208            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6209                    mHeavyWeightProcess.userId, 0));
6210            mHeavyWeightProcess = null;
6211        }
6212        boolean needRestart = false;
6213        if (app.pid > 0 && app.pid != MY_PID) {
6214            int pid = app.pid;
6215            synchronized (mPidsSelfLocked) {
6216                mPidsSelfLocked.remove(pid);
6217                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6218            }
6219            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6220            if (app.isolated) {
6221                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6222            }
6223            boolean willRestart = false;
6224            if (app.persistent && !app.isolated) {
6225                if (!callerWillRestart) {
6226                    willRestart = true;
6227                } else {
6228                    needRestart = true;
6229                }
6230            }
6231            app.kill(reason, true);
6232            handleAppDiedLocked(app, willRestart, allowRestart);
6233            if (willRestart) {
6234                removeLruProcessLocked(app);
6235                addAppLocked(app.info, false, null /* ABI override */);
6236            }
6237        } else {
6238            mRemovedProcesses.add(app);
6239        }
6240
6241        return needRestart;
6242    }
6243
6244    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6245        cleanupAppInLaunchingProvidersLocked(app, true);
6246        removeProcessLocked(app, false, true, "timeout publishing content providers");
6247    }
6248
6249    private final void processStartTimedOutLocked(ProcessRecord app) {
6250        final int pid = app.pid;
6251        boolean gone = false;
6252        synchronized (mPidsSelfLocked) {
6253            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6254            if (knownApp != null && knownApp.thread == null) {
6255                mPidsSelfLocked.remove(pid);
6256                gone = true;
6257            }
6258        }
6259
6260        if (gone) {
6261            Slog.w(TAG, "Process " + app + " failed to attach");
6262            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6263                    pid, app.uid, app.processName);
6264            removeProcessNameLocked(app.processName, app.uid);
6265            if (mHeavyWeightProcess == app) {
6266                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6267                        mHeavyWeightProcess.userId, 0));
6268                mHeavyWeightProcess = null;
6269            }
6270            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6271            if (app.isolated) {
6272                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6273            }
6274            // Take care of any launching providers waiting for this process.
6275            cleanupAppInLaunchingProvidersLocked(app, true);
6276            // Take care of any services that are waiting for the process.
6277            mServices.processStartTimedOutLocked(app);
6278            app.kill("start timeout", true);
6279            removeLruProcessLocked(app);
6280            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6281                Slog.w(TAG, "Unattached app died before backup, skipping");
6282                try {
6283                    IBackupManager bm = IBackupManager.Stub.asInterface(
6284                            ServiceManager.getService(Context.BACKUP_SERVICE));
6285                    bm.agentDisconnected(app.info.packageName);
6286                } catch (RemoteException e) {
6287                    // Can't happen; the backup manager is local
6288                }
6289            }
6290            if (isPendingBroadcastProcessLocked(pid)) {
6291                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6292                skipPendingBroadcastLocked(pid);
6293            }
6294        } else {
6295            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6296        }
6297    }
6298
6299    private final boolean attachApplicationLocked(IApplicationThread thread,
6300            int pid) {
6301
6302        // Find the application record that is being attached...  either via
6303        // the pid if we are running in multiple processes, or just pull the
6304        // next app record if we are emulating process with anonymous threads.
6305        ProcessRecord app;
6306        if (pid != MY_PID && pid >= 0) {
6307            synchronized (mPidsSelfLocked) {
6308                app = mPidsSelfLocked.get(pid);
6309            }
6310        } else {
6311            app = null;
6312        }
6313
6314        if (app == null) {
6315            Slog.w(TAG, "No pending application record for pid " + pid
6316                    + " (IApplicationThread " + thread + "); dropping process");
6317            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6318            if (pid > 0 && pid != MY_PID) {
6319                Process.killProcessQuiet(pid);
6320                //TODO: killProcessGroup(app.info.uid, pid);
6321            } else {
6322                try {
6323                    thread.scheduleExit();
6324                } catch (Exception e) {
6325                    // Ignore exceptions.
6326                }
6327            }
6328            return false;
6329        }
6330
6331        // If this application record is still attached to a previous
6332        // process, clean it up now.
6333        if (app.thread != null) {
6334            handleAppDiedLocked(app, true, true);
6335        }
6336
6337        // Tell the process all about itself.
6338
6339        if (DEBUG_ALL) Slog.v(
6340                TAG, "Binding process pid " + pid + " to record " + app);
6341
6342        final String processName = app.processName;
6343        try {
6344            AppDeathRecipient adr = new AppDeathRecipient(
6345                    app, pid, thread);
6346            thread.asBinder().linkToDeath(adr, 0);
6347            app.deathRecipient = adr;
6348        } catch (RemoteException e) {
6349            app.resetPackageList(mProcessStats);
6350            startProcessLocked(app, "link fail", processName);
6351            return false;
6352        }
6353
6354        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6355
6356        app.makeActive(thread, mProcessStats);
6357        app.curAdj = app.setAdj = ProcessList.INVALID_ADJ;
6358        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6359        app.forcingToForeground = null;
6360        updateProcessForegroundLocked(app, false, false);
6361        app.hasShownUi = false;
6362        app.debugging = false;
6363        app.cached = false;
6364        app.killedByAm = false;
6365
6366        // We carefully use the same state that PackageManager uses for
6367        // filtering, since we use this flag to decide if we need to install
6368        // providers when user is unlocked later
6369        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6370
6371        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6372
6373        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6374        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6375
6376        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6377            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6378            msg.obj = app;
6379            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6380        }
6381
6382        if (!normalMode) {
6383            Slog.i(TAG, "Launching preboot mode app: " + app);
6384        }
6385
6386        if (DEBUG_ALL) Slog.v(
6387            TAG, "New app record " + app
6388            + " thread=" + thread.asBinder() + " pid=" + pid);
6389        try {
6390            int testMode = IApplicationThread.DEBUG_OFF;
6391            if (mDebugApp != null && mDebugApp.equals(processName)) {
6392                testMode = mWaitForDebugger
6393                    ? IApplicationThread.DEBUG_WAIT
6394                    : IApplicationThread.DEBUG_ON;
6395                app.debugging = true;
6396                if (mDebugTransient) {
6397                    mDebugApp = mOrigDebugApp;
6398                    mWaitForDebugger = mOrigWaitForDebugger;
6399                }
6400            }
6401            String profileFile = app.instrumentationProfileFile;
6402            ParcelFileDescriptor profileFd = null;
6403            int samplingInterval = 0;
6404            boolean profileAutoStop = false;
6405            if (mProfileApp != null && mProfileApp.equals(processName)) {
6406                mProfileProc = app;
6407                profileFile = mProfileFile;
6408                profileFd = mProfileFd;
6409                samplingInterval = mSamplingInterval;
6410                profileAutoStop = mAutoStopProfiler;
6411            }
6412            boolean enableTrackAllocation = false;
6413            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6414                enableTrackAllocation = true;
6415                mTrackAllocationApp = null;
6416            }
6417
6418            // If the app is being launched for restore or full backup, set it up specially
6419            boolean isRestrictedBackupMode = false;
6420            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6421                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6422                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6423                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6424                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6425            }
6426
6427            if (app.instrumentationClass != null) {
6428                notifyPackageUse(app.instrumentationClass.getPackageName(),
6429                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6430            }
6431            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6432                    + processName + " with config " + mConfiguration);
6433            ApplicationInfo appInfo = app.instrumentationInfo != null
6434                    ? app.instrumentationInfo : app.info;
6435            app.compat = compatibilityInfoForPackageLocked(appInfo);
6436            if (profileFd != null) {
6437                profileFd = profileFd.dup();
6438            }
6439            ProfilerInfo profilerInfo = profileFile == null ? null
6440                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6441            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6442                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6443                    app.instrumentationUiAutomationConnection, testMode,
6444                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6445                    isRestrictedBackupMode || !normalMode, app.persistent,
6446                    new Configuration(mConfiguration), app.compat,
6447                    getCommonServicesLocked(app.isolated),
6448                    mCoreSettingsObserver.getCoreSettingsLocked());
6449            updateLruProcessLocked(app, false, null);
6450            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6451        } catch (Exception e) {
6452            // todo: Yikes!  What should we do?  For now we will try to
6453            // start another process, but that could easily get us in
6454            // an infinite loop of restarting processes...
6455            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6456
6457            app.resetPackageList(mProcessStats);
6458            app.unlinkDeathRecipient();
6459            startProcessLocked(app, "bind fail", processName);
6460            return false;
6461        }
6462
6463        // Remove this record from the list of starting applications.
6464        mPersistentStartingProcesses.remove(app);
6465        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6466                "Attach application locked removing on hold: " + app);
6467        mProcessesOnHold.remove(app);
6468
6469        boolean badApp = false;
6470        boolean didSomething = false;
6471
6472        // See if the top visible activity is waiting to run in this process...
6473        if (normalMode) {
6474            try {
6475                if (mStackSupervisor.attachApplicationLocked(app)) {
6476                    didSomething = true;
6477                }
6478            } catch (Exception e) {
6479                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6480                badApp = true;
6481            }
6482        }
6483
6484        // Find any services that should be running in this process...
6485        if (!badApp) {
6486            try {
6487                didSomething |= mServices.attachApplicationLocked(app, processName);
6488            } catch (Exception e) {
6489                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6490                badApp = true;
6491            }
6492        }
6493
6494        // Check if a next-broadcast receiver is in this process...
6495        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6496            try {
6497                didSomething |= sendPendingBroadcastsLocked(app);
6498            } catch (Exception e) {
6499                // If the app died trying to launch the receiver we declare it 'bad'
6500                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6501                badApp = true;
6502            }
6503        }
6504
6505        // Check whether the next backup agent is in this process...
6506        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6507            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6508                    "New app is backup target, launching agent for " + app);
6509            notifyPackageUse(mBackupTarget.appInfo.packageName,
6510                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6511            try {
6512                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6513                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6514                        mBackupTarget.backupMode);
6515            } catch (Exception e) {
6516                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6517                badApp = true;
6518            }
6519        }
6520
6521        if (badApp) {
6522            app.kill("error during init", true);
6523            handleAppDiedLocked(app, false, true);
6524            return false;
6525        }
6526
6527        if (!didSomething) {
6528            updateOomAdjLocked();
6529        }
6530
6531        return true;
6532    }
6533
6534    @Override
6535    public final void attachApplication(IApplicationThread thread) {
6536        synchronized (this) {
6537            int callingPid = Binder.getCallingPid();
6538            final long origId = Binder.clearCallingIdentity();
6539            attachApplicationLocked(thread, callingPid);
6540            Binder.restoreCallingIdentity(origId);
6541        }
6542    }
6543
6544    @Override
6545    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6546        final long origId = Binder.clearCallingIdentity();
6547        synchronized (this) {
6548            ActivityStack stack = ActivityRecord.getStackLocked(token);
6549            if (stack != null) {
6550                ActivityRecord r =
6551                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6552                if (stopProfiling) {
6553                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6554                        try {
6555                            mProfileFd.close();
6556                        } catch (IOException e) {
6557                        }
6558                        clearProfilerLocked();
6559                    }
6560                }
6561            }
6562        }
6563        Binder.restoreCallingIdentity(origId);
6564    }
6565
6566    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6567        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6568                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6569    }
6570
6571    void enableScreenAfterBoot() {
6572        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6573                SystemClock.uptimeMillis());
6574        mWindowManager.enableScreenAfterBoot();
6575
6576        synchronized (this) {
6577            updateEventDispatchingLocked();
6578        }
6579    }
6580
6581    @Override
6582    public void showBootMessage(final CharSequence msg, final boolean always) {
6583        if (Binder.getCallingUid() != Process.myUid()) {
6584            // These days only the core system can call this, so apps can't get in
6585            // the way of what we show about running them.
6586        }
6587        mWindowManager.showBootMessage(msg, always);
6588    }
6589
6590    @Override
6591    public void keyguardWaitingForActivityDrawn() {
6592        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6593        final long token = Binder.clearCallingIdentity();
6594        try {
6595            synchronized (this) {
6596                if (DEBUG_LOCKSCREEN) logLockScreen("");
6597                mWindowManager.keyguardWaitingForActivityDrawn();
6598                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6599                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6600                    updateSleepIfNeededLocked();
6601                }
6602            }
6603        } finally {
6604            Binder.restoreCallingIdentity(token);
6605        }
6606    }
6607
6608    @Override
6609    public void keyguardGoingAway(int flags) {
6610        enforceNotIsolatedCaller("keyguardGoingAway");
6611        final long token = Binder.clearCallingIdentity();
6612        try {
6613            synchronized (this) {
6614                if (DEBUG_LOCKSCREEN) logLockScreen("");
6615                mWindowManager.keyguardGoingAway(flags);
6616                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6617                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6618                    updateSleepIfNeededLocked();
6619
6620                    // Some stack visibility might change (e.g. docked stack)
6621                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6622                    applyVrModeIfNeededLocked(mFocusedActivity, true);
6623                }
6624            }
6625        } finally {
6626            Binder.restoreCallingIdentity(token);
6627        }
6628    }
6629
6630    final void finishBooting() {
6631        synchronized (this) {
6632            if (!mBootAnimationComplete) {
6633                mCallFinishBooting = true;
6634                return;
6635            }
6636            mCallFinishBooting = false;
6637        }
6638
6639        ArraySet<String> completedIsas = new ArraySet<String>();
6640        for (String abi : Build.SUPPORTED_ABIS) {
6641            Process.establishZygoteConnectionForAbi(abi);
6642            final String instructionSet = VMRuntime.getInstructionSet(abi);
6643            if (!completedIsas.contains(instructionSet)) {
6644                try {
6645                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6646                } catch (InstallerException e) {
6647                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6648                            e.getMessage() +")");
6649                }
6650                completedIsas.add(instructionSet);
6651            }
6652        }
6653
6654        IntentFilter pkgFilter = new IntentFilter();
6655        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6656        pkgFilter.addDataScheme("package");
6657        mContext.registerReceiver(new BroadcastReceiver() {
6658            @Override
6659            public void onReceive(Context context, Intent intent) {
6660                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6661                if (pkgs != null) {
6662                    for (String pkg : pkgs) {
6663                        synchronized (ActivityManagerService.this) {
6664                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6665                                    0, "query restart")) {
6666                                setResultCode(Activity.RESULT_OK);
6667                                return;
6668                            }
6669                        }
6670                    }
6671                }
6672            }
6673        }, pkgFilter);
6674
6675        IntentFilter dumpheapFilter = new IntentFilter();
6676        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6677        mContext.registerReceiver(new BroadcastReceiver() {
6678            @Override
6679            public void onReceive(Context context, Intent intent) {
6680                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6681                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6682                } else {
6683                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6684                }
6685            }
6686        }, dumpheapFilter);
6687
6688        // Let system services know.
6689        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6690
6691        synchronized (this) {
6692            // Ensure that any processes we had put on hold are now started
6693            // up.
6694            final int NP = mProcessesOnHold.size();
6695            if (NP > 0) {
6696                ArrayList<ProcessRecord> procs =
6697                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6698                for (int ip=0; ip<NP; ip++) {
6699                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6700                            + procs.get(ip));
6701                    startProcessLocked(procs.get(ip), "on-hold", null);
6702                }
6703            }
6704
6705            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6706                // Start looking for apps that are abusing wake locks.
6707                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6708                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6709                // Tell anyone interested that we are done booting!
6710                SystemProperties.set("sys.boot_completed", "1");
6711
6712                // And trigger dev.bootcomplete if we are not showing encryption progress
6713                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6714                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6715                    SystemProperties.set("dev.bootcomplete", "1");
6716                }
6717                mUserController.sendBootCompletedLocked(
6718                        new IIntentReceiver.Stub() {
6719                            @Override
6720                            public void performReceive(Intent intent, int resultCode,
6721                                    String data, Bundle extras, boolean ordered,
6722                                    boolean sticky, int sendingUser) {
6723                                synchronized (ActivityManagerService.this) {
6724                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6725                                            true, false);
6726                                }
6727                            }
6728                        });
6729                scheduleStartProfilesLocked();
6730            }
6731        }
6732    }
6733
6734    @Override
6735    public void bootAnimationComplete() {
6736        final boolean callFinishBooting;
6737        synchronized (this) {
6738            callFinishBooting = mCallFinishBooting;
6739            mBootAnimationComplete = true;
6740        }
6741        if (callFinishBooting) {
6742            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6743            finishBooting();
6744            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6745        }
6746    }
6747
6748    final void ensureBootCompleted() {
6749        boolean booting;
6750        boolean enableScreen;
6751        synchronized (this) {
6752            booting = mBooting;
6753            mBooting = false;
6754            enableScreen = !mBooted;
6755            mBooted = true;
6756        }
6757
6758        if (booting) {
6759            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6760            finishBooting();
6761            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6762        }
6763
6764        if (enableScreen) {
6765            enableScreenAfterBoot();
6766        }
6767    }
6768
6769    @Override
6770    public final void activityResumed(IBinder token) {
6771        final long origId = Binder.clearCallingIdentity();
6772        synchronized(this) {
6773            ActivityStack stack = ActivityRecord.getStackLocked(token);
6774            if (stack != null) {
6775                stack.activityResumedLocked(token);
6776            }
6777        }
6778        Binder.restoreCallingIdentity(origId);
6779    }
6780
6781    @Override
6782    public final void activityPaused(IBinder token) {
6783        final long origId = Binder.clearCallingIdentity();
6784        synchronized(this) {
6785            ActivityStack stack = ActivityRecord.getStackLocked(token);
6786            if (stack != null) {
6787                stack.activityPausedLocked(token, false);
6788            }
6789        }
6790        Binder.restoreCallingIdentity(origId);
6791    }
6792
6793    @Override
6794    public final void activityStopped(IBinder token, Bundle icicle,
6795            PersistableBundle persistentState, CharSequence description) {
6796        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6797
6798        // Refuse possible leaked file descriptors
6799        if (icicle != null && icicle.hasFileDescriptors()) {
6800            throw new IllegalArgumentException("File descriptors passed in Bundle");
6801        }
6802
6803        final long origId = Binder.clearCallingIdentity();
6804
6805        synchronized (this) {
6806            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6807            if (r != null) {
6808                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6809            }
6810        }
6811
6812        trimApplications();
6813
6814        Binder.restoreCallingIdentity(origId);
6815    }
6816
6817    @Override
6818    public final void activityDestroyed(IBinder token) {
6819        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6820        synchronized (this) {
6821            ActivityStack stack = ActivityRecord.getStackLocked(token);
6822            if (stack != null) {
6823                stack.activityDestroyedLocked(token, "activityDestroyed");
6824            }
6825        }
6826    }
6827
6828    @Override
6829    public final void activityRelaunched(IBinder token) {
6830        final long origId = Binder.clearCallingIdentity();
6831        synchronized (this) {
6832            mStackSupervisor.activityRelaunchedLocked(token);
6833        }
6834        Binder.restoreCallingIdentity(origId);
6835    }
6836
6837    @Override
6838    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6839            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6840        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6841                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6842        synchronized (this) {
6843            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6844            if (record == null) {
6845                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6846                        + "found for: " + token);
6847            }
6848            record.setSizeConfigurations(horizontalSizeConfiguration,
6849                    verticalSizeConfigurations, smallestSizeConfigurations);
6850        }
6851    }
6852
6853    @Override
6854    public final void backgroundResourcesReleased(IBinder token) {
6855        final long origId = Binder.clearCallingIdentity();
6856        try {
6857            synchronized (this) {
6858                ActivityStack stack = ActivityRecord.getStackLocked(token);
6859                if (stack != null) {
6860                    stack.backgroundResourcesReleased();
6861                }
6862            }
6863        } finally {
6864            Binder.restoreCallingIdentity(origId);
6865        }
6866    }
6867
6868    @Override
6869    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6870        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6871    }
6872
6873    @Override
6874    public final void notifyEnterAnimationComplete(IBinder token) {
6875        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6876    }
6877
6878    @Override
6879    public String getCallingPackage(IBinder token) {
6880        synchronized (this) {
6881            ActivityRecord r = getCallingRecordLocked(token);
6882            return r != null ? r.info.packageName : null;
6883        }
6884    }
6885
6886    @Override
6887    public ComponentName getCallingActivity(IBinder token) {
6888        synchronized (this) {
6889            ActivityRecord r = getCallingRecordLocked(token);
6890            return r != null ? r.intent.getComponent() : null;
6891        }
6892    }
6893
6894    private ActivityRecord getCallingRecordLocked(IBinder token) {
6895        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6896        if (r == null) {
6897            return null;
6898        }
6899        return r.resultTo;
6900    }
6901
6902    @Override
6903    public ComponentName getActivityClassForToken(IBinder token) {
6904        synchronized(this) {
6905            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6906            if (r == null) {
6907                return null;
6908            }
6909            return r.intent.getComponent();
6910        }
6911    }
6912
6913    @Override
6914    public String getPackageForToken(IBinder token) {
6915        synchronized(this) {
6916            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6917            if (r == null) {
6918                return null;
6919            }
6920            return r.packageName;
6921        }
6922    }
6923
6924    @Override
6925    public boolean isRootVoiceInteraction(IBinder token) {
6926        synchronized(this) {
6927            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6928            if (r == null) {
6929                return false;
6930            }
6931            return r.rootVoiceInteraction;
6932        }
6933    }
6934
6935    @Override
6936    public IIntentSender getIntentSender(int type,
6937            String packageName, IBinder token, String resultWho,
6938            int requestCode, Intent[] intents, String[] resolvedTypes,
6939            int flags, Bundle bOptions, int userId) {
6940        enforceNotIsolatedCaller("getIntentSender");
6941        // Refuse possible leaked file descriptors
6942        if (intents != null) {
6943            if (intents.length < 1) {
6944                throw new IllegalArgumentException("Intents array length must be >= 1");
6945            }
6946            for (int i=0; i<intents.length; i++) {
6947                Intent intent = intents[i];
6948                if (intent != null) {
6949                    if (intent.hasFileDescriptors()) {
6950                        throw new IllegalArgumentException("File descriptors passed in Intent");
6951                    }
6952                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6953                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6954                        throw new IllegalArgumentException(
6955                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6956                    }
6957                    intents[i] = new Intent(intent);
6958                }
6959            }
6960            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6961                throw new IllegalArgumentException(
6962                        "Intent array length does not match resolvedTypes length");
6963            }
6964        }
6965        if (bOptions != null) {
6966            if (bOptions.hasFileDescriptors()) {
6967                throw new IllegalArgumentException("File descriptors passed in options");
6968            }
6969        }
6970
6971        synchronized(this) {
6972            int callingUid = Binder.getCallingUid();
6973            int origUserId = userId;
6974            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6975                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6976                    ALLOW_NON_FULL, "getIntentSender", null);
6977            if (origUserId == UserHandle.USER_CURRENT) {
6978                // We don't want to evaluate this until the pending intent is
6979                // actually executed.  However, we do want to always do the
6980                // security checking for it above.
6981                userId = UserHandle.USER_CURRENT;
6982            }
6983            try {
6984                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6985                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
6986                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
6987                    if (!UserHandle.isSameApp(callingUid, uid)) {
6988                        String msg = "Permission Denial: getIntentSender() from pid="
6989                            + Binder.getCallingPid()
6990                            + ", uid=" + Binder.getCallingUid()
6991                            + ", (need uid=" + uid + ")"
6992                            + " is not allowed to send as package " + packageName;
6993                        Slog.w(TAG, msg);
6994                        throw new SecurityException(msg);
6995                    }
6996                }
6997
6998                return getIntentSenderLocked(type, packageName, callingUid, userId,
6999                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7000
7001            } catch (RemoteException e) {
7002                throw new SecurityException(e);
7003            }
7004        }
7005    }
7006
7007    IIntentSender getIntentSenderLocked(int type, String packageName,
7008            int callingUid, int userId, IBinder token, String resultWho,
7009            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7010            Bundle bOptions) {
7011        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7012        ActivityRecord activity = null;
7013        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7014            activity = ActivityRecord.isInStackLocked(token);
7015            if (activity == null) {
7016                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7017                return null;
7018            }
7019            if (activity.finishing) {
7020                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7021                return null;
7022            }
7023        }
7024
7025        // We're going to be splicing together extras before sending, so we're
7026        // okay poking into any contained extras.
7027        if (intents != null) {
7028            for (int i = 0; i < intents.length; i++) {
7029                intents[i].setDefusable(true);
7030            }
7031        }
7032        Bundle.setDefusable(bOptions, true);
7033
7034        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7035        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7036        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7037        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7038                |PendingIntent.FLAG_UPDATE_CURRENT);
7039
7040        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7041                type, packageName, activity, resultWho,
7042                requestCode, intents, resolvedTypes, flags, bOptions, userId);
7043        WeakReference<PendingIntentRecord> ref;
7044        ref = mIntentSenderRecords.get(key);
7045        PendingIntentRecord rec = ref != null ? ref.get() : null;
7046        if (rec != null) {
7047            if (!cancelCurrent) {
7048                if (updateCurrent) {
7049                    if (rec.key.requestIntent != null) {
7050                        rec.key.requestIntent.replaceExtras(intents != null ?
7051                                intents[intents.length - 1] : null);
7052                    }
7053                    if (intents != null) {
7054                        intents[intents.length-1] = rec.key.requestIntent;
7055                        rec.key.allIntents = intents;
7056                        rec.key.allResolvedTypes = resolvedTypes;
7057                    } else {
7058                        rec.key.allIntents = null;
7059                        rec.key.allResolvedTypes = null;
7060                    }
7061                }
7062                return rec;
7063            }
7064            rec.canceled = true;
7065            mIntentSenderRecords.remove(key);
7066        }
7067        if (noCreate) {
7068            return rec;
7069        }
7070        rec = new PendingIntentRecord(this, key, callingUid);
7071        mIntentSenderRecords.put(key, rec.ref);
7072        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7073            if (activity.pendingResults == null) {
7074                activity.pendingResults
7075                        = new HashSet<WeakReference<PendingIntentRecord>>();
7076            }
7077            activity.pendingResults.add(rec.ref);
7078        }
7079        return rec;
7080    }
7081
7082    @Override
7083    public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7084            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7085        if (target instanceof PendingIntentRecord) {
7086            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7087                    finishedReceiver, requiredPermission, options);
7088        } else {
7089            if (intent == null) {
7090                // Weird case: someone has given us their own custom IIntentSender, and now
7091                // they have someone else trying to send to it but of course this isn't
7092                // really a PendingIntent, so there is no base Intent, and the caller isn't
7093                // supplying an Intent... but we never want to dispatch a null Intent to
7094                // a receiver, so um...  let's make something up.
7095                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7096                intent = new Intent(Intent.ACTION_MAIN);
7097            }
7098            try {
7099                target.send(code, intent, resolvedType, null, requiredPermission, options);
7100            } catch (RemoteException e) {
7101            }
7102            // Platform code can rely on getting a result back when the send is done, but if
7103            // this intent sender is from outside of the system we can't rely on it doing that.
7104            // So instead we don't give it the result receiver, and instead just directly
7105            // report the finish immediately.
7106            if (finishedReceiver != null) {
7107                try {
7108                    finishedReceiver.performReceive(intent, 0,
7109                            null, null, false, false, UserHandle.getCallingUserId());
7110                } catch (RemoteException e) {
7111                }
7112            }
7113            return 0;
7114        }
7115    }
7116
7117    @Override
7118    public void cancelIntentSender(IIntentSender sender) {
7119        if (!(sender instanceof PendingIntentRecord)) {
7120            return;
7121        }
7122        synchronized(this) {
7123            PendingIntentRecord rec = (PendingIntentRecord)sender;
7124            try {
7125                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7126                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7127                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7128                    String msg = "Permission Denial: cancelIntentSender() from pid="
7129                        + Binder.getCallingPid()
7130                        + ", uid=" + Binder.getCallingUid()
7131                        + " is not allowed to cancel packges "
7132                        + rec.key.packageName;
7133                    Slog.w(TAG, msg);
7134                    throw new SecurityException(msg);
7135                }
7136            } catch (RemoteException e) {
7137                throw new SecurityException(e);
7138            }
7139            cancelIntentSenderLocked(rec, true);
7140        }
7141    }
7142
7143    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7144        rec.canceled = true;
7145        mIntentSenderRecords.remove(rec.key);
7146        if (cleanActivity && rec.key.activity != null) {
7147            rec.key.activity.pendingResults.remove(rec.ref);
7148        }
7149    }
7150
7151    @Override
7152    public String getPackageForIntentSender(IIntentSender pendingResult) {
7153        if (!(pendingResult instanceof PendingIntentRecord)) {
7154            return null;
7155        }
7156        try {
7157            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7158            return res.key.packageName;
7159        } catch (ClassCastException e) {
7160        }
7161        return null;
7162    }
7163
7164    @Override
7165    public int getUidForIntentSender(IIntentSender sender) {
7166        if (sender instanceof PendingIntentRecord) {
7167            try {
7168                PendingIntentRecord res = (PendingIntentRecord)sender;
7169                return res.uid;
7170            } catch (ClassCastException e) {
7171            }
7172        }
7173        return -1;
7174    }
7175
7176    @Override
7177    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7178        if (!(pendingResult instanceof PendingIntentRecord)) {
7179            return false;
7180        }
7181        try {
7182            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7183            if (res.key.allIntents == null) {
7184                return false;
7185            }
7186            for (int i=0; i<res.key.allIntents.length; i++) {
7187                Intent intent = res.key.allIntents[i];
7188                if (intent.getPackage() != null && intent.getComponent() != null) {
7189                    return false;
7190                }
7191            }
7192            return true;
7193        } catch (ClassCastException e) {
7194        }
7195        return false;
7196    }
7197
7198    @Override
7199    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7200        if (!(pendingResult instanceof PendingIntentRecord)) {
7201            return false;
7202        }
7203        try {
7204            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7205            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7206                return true;
7207            }
7208            return false;
7209        } catch (ClassCastException e) {
7210        }
7211        return false;
7212    }
7213
7214    @Override
7215    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7216        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7217                "getIntentForIntentSender()");
7218        if (!(pendingResult instanceof PendingIntentRecord)) {
7219            return null;
7220        }
7221        try {
7222            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7223            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7224        } catch (ClassCastException e) {
7225        }
7226        return null;
7227    }
7228
7229    @Override
7230    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7231        if (!(pendingResult instanceof PendingIntentRecord)) {
7232            return null;
7233        }
7234        try {
7235            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7236            synchronized (this) {
7237                return getTagForIntentSenderLocked(res, prefix);
7238            }
7239        } catch (ClassCastException e) {
7240        }
7241        return null;
7242    }
7243
7244    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7245        final Intent intent = res.key.requestIntent;
7246        if (intent != null) {
7247            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7248                    || res.lastTagPrefix.equals(prefix))) {
7249                return res.lastTag;
7250            }
7251            res.lastTagPrefix = prefix;
7252            final StringBuilder sb = new StringBuilder(128);
7253            if (prefix != null) {
7254                sb.append(prefix);
7255            }
7256            if (intent.getAction() != null) {
7257                sb.append(intent.getAction());
7258            } else if (intent.getComponent() != null) {
7259                intent.getComponent().appendShortString(sb);
7260            } else {
7261                sb.append("?");
7262            }
7263            return res.lastTag = sb.toString();
7264        }
7265        return null;
7266    }
7267
7268    @Override
7269    public void setProcessLimit(int max) {
7270        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7271                "setProcessLimit()");
7272        synchronized (this) {
7273            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7274            mProcessLimitOverride = max;
7275        }
7276        trimApplications();
7277    }
7278
7279    @Override
7280    public int getProcessLimit() {
7281        synchronized (this) {
7282            return mProcessLimitOverride;
7283        }
7284    }
7285
7286    void foregroundTokenDied(ForegroundToken token) {
7287        synchronized (ActivityManagerService.this) {
7288            synchronized (mPidsSelfLocked) {
7289                ForegroundToken cur
7290                    = mForegroundProcesses.get(token.pid);
7291                if (cur != token) {
7292                    return;
7293                }
7294                mForegroundProcesses.remove(token.pid);
7295                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7296                if (pr == null) {
7297                    return;
7298                }
7299                pr.forcingToForeground = null;
7300                updateProcessForegroundLocked(pr, false, false);
7301            }
7302            updateOomAdjLocked();
7303        }
7304    }
7305
7306    @Override
7307    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7308        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7309                "setProcessForeground()");
7310        synchronized(this) {
7311            boolean changed = false;
7312
7313            synchronized (mPidsSelfLocked) {
7314                ProcessRecord pr = mPidsSelfLocked.get(pid);
7315                if (pr == null && isForeground) {
7316                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7317                    return;
7318                }
7319                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7320                if (oldToken != null) {
7321                    oldToken.token.unlinkToDeath(oldToken, 0);
7322                    mForegroundProcesses.remove(pid);
7323                    if (pr != null) {
7324                        pr.forcingToForeground = null;
7325                    }
7326                    changed = true;
7327                }
7328                if (isForeground && token != null) {
7329                    ForegroundToken newToken = new ForegroundToken() {
7330                        @Override
7331                        public void binderDied() {
7332                            foregroundTokenDied(this);
7333                        }
7334                    };
7335                    newToken.pid = pid;
7336                    newToken.token = token;
7337                    try {
7338                        token.linkToDeath(newToken, 0);
7339                        mForegroundProcesses.put(pid, newToken);
7340                        pr.forcingToForeground = token;
7341                        changed = true;
7342                    } catch (RemoteException e) {
7343                        // If the process died while doing this, we will later
7344                        // do the cleanup with the process death link.
7345                    }
7346                }
7347            }
7348
7349            if (changed) {
7350                updateOomAdjLocked();
7351            }
7352        }
7353    }
7354
7355    @Override
7356    public boolean isAppForeground(int uid) throws RemoteException {
7357        synchronized (this) {
7358            UidRecord uidRec = mActiveUids.get(uid);
7359            if (uidRec == null || uidRec.idle) {
7360                return false;
7361            }
7362            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7363        }
7364    }
7365
7366    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7367    // be guarded by permission checking.
7368    int getUidState(int uid) {
7369        synchronized (this) {
7370            UidRecord uidRec = mActiveUids.get(uid);
7371            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7372        }
7373    }
7374
7375    @Override
7376    public boolean isInMultiWindowMode(IBinder token) {
7377        final long origId = Binder.clearCallingIdentity();
7378        try {
7379            synchronized(this) {
7380                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7381                if (r == null) {
7382                    return false;
7383                }
7384                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7385                return !r.task.mFullscreen;
7386            }
7387        } finally {
7388            Binder.restoreCallingIdentity(origId);
7389        }
7390    }
7391
7392    @Override
7393    public boolean isInPictureInPictureMode(IBinder token) {
7394        final long origId = Binder.clearCallingIdentity();
7395        try {
7396            synchronized(this) {
7397                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7398                if (stack == null) {
7399                    return false;
7400                }
7401                return stack.mStackId == PINNED_STACK_ID;
7402            }
7403        } finally {
7404            Binder.restoreCallingIdentity(origId);
7405        }
7406    }
7407
7408    @Override
7409    public void enterPictureInPictureMode(IBinder token) {
7410        final long origId = Binder.clearCallingIdentity();
7411        try {
7412            synchronized(this) {
7413                if (!mSupportsPictureInPicture) {
7414                    throw new IllegalStateException("enterPictureInPictureMode: "
7415                            + "Device doesn't support picture-in-picture mode.");
7416                }
7417
7418                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7419
7420                if (r == null) {
7421                    throw new IllegalStateException("enterPictureInPictureMode: "
7422                            + "Can't find activity for token=" + token);
7423                }
7424
7425                if (!r.supportsPictureInPicture()) {
7426                    throw new IllegalArgumentException("enterPictureInPictureMode: "
7427                            + "Picture-In-Picture not supported for r=" + r);
7428                }
7429
7430                // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
7431                // current bounds.
7432                final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
7433                final Rect bounds = (pinnedStack != null)
7434                        ? pinnedStack.mBounds : mDefaultPinnedStackBounds;
7435
7436                mStackSupervisor.moveActivityToPinnedStackLocked(
7437                        r, "enterPictureInPictureMode", bounds);
7438            }
7439        } finally {
7440            Binder.restoreCallingIdentity(origId);
7441        }
7442    }
7443
7444    // =========================================================
7445    // PROCESS INFO
7446    // =========================================================
7447
7448    static class ProcessInfoService extends IProcessInfoService.Stub {
7449        final ActivityManagerService mActivityManagerService;
7450        ProcessInfoService(ActivityManagerService activityManagerService) {
7451            mActivityManagerService = activityManagerService;
7452        }
7453
7454        @Override
7455        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7456            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7457                    /*in*/ pids, /*out*/ states, null);
7458        }
7459
7460        @Override
7461        public void getProcessStatesAndOomScoresFromPids(
7462                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7463            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7464                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7465        }
7466    }
7467
7468    /**
7469     * For each PID in the given input array, write the current process state
7470     * for that process into the states array, or -1 to indicate that no
7471     * process with the given PID exists. If scores array is provided, write
7472     * the oom score for the process into the scores array, with INVALID_ADJ
7473     * indicating the PID doesn't exist.
7474     */
7475    public void getProcessStatesAndOomScoresForPIDs(
7476            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7477        if (scores != null) {
7478            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7479                    "getProcessStatesAndOomScoresForPIDs()");
7480        }
7481
7482        if (pids == null) {
7483            throw new NullPointerException("pids");
7484        } else if (states == null) {
7485            throw new NullPointerException("states");
7486        } else if (pids.length != states.length) {
7487            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7488        } else if (scores != null && pids.length != scores.length) {
7489            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7490        }
7491
7492        synchronized (mPidsSelfLocked) {
7493            for (int i = 0; i < pids.length; i++) {
7494                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7495                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7496                        pr.curProcState;
7497                if (scores != null) {
7498                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7499                }
7500            }
7501        }
7502    }
7503
7504    // =========================================================
7505    // PERMISSIONS
7506    // =========================================================
7507
7508    static class PermissionController extends IPermissionController.Stub {
7509        ActivityManagerService mActivityManagerService;
7510        PermissionController(ActivityManagerService activityManagerService) {
7511            mActivityManagerService = activityManagerService;
7512        }
7513
7514        @Override
7515        public boolean checkPermission(String permission, int pid, int uid) {
7516            return mActivityManagerService.checkPermission(permission, pid,
7517                    uid) == PackageManager.PERMISSION_GRANTED;
7518        }
7519
7520        @Override
7521        public String[] getPackagesForUid(int uid) {
7522            return mActivityManagerService.mContext.getPackageManager()
7523                    .getPackagesForUid(uid);
7524        }
7525
7526        @Override
7527        public boolean isRuntimePermission(String permission) {
7528            try {
7529                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7530                        .getPermissionInfo(permission, 0);
7531                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7532            } catch (NameNotFoundException nnfe) {
7533                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7534            }
7535            return false;
7536        }
7537    }
7538
7539    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7540        @Override
7541        public int checkComponentPermission(String permission, int pid, int uid,
7542                int owningUid, boolean exported) {
7543            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7544                    owningUid, exported);
7545        }
7546
7547        @Override
7548        public Object getAMSLock() {
7549            return ActivityManagerService.this;
7550        }
7551    }
7552
7553    /**
7554     * This can be called with or without the global lock held.
7555     */
7556    int checkComponentPermission(String permission, int pid, int uid,
7557            int owningUid, boolean exported) {
7558        if (pid == MY_PID) {
7559            return PackageManager.PERMISSION_GRANTED;
7560        }
7561        return ActivityManager.checkComponentPermission(permission, uid,
7562                owningUid, exported);
7563    }
7564
7565    /**
7566     * As the only public entry point for permissions checking, this method
7567     * can enforce the semantic that requesting a check on a null global
7568     * permission is automatically denied.  (Internally a null permission
7569     * string is used when calling {@link #checkComponentPermission} in cases
7570     * when only uid-based security is needed.)
7571     *
7572     * This can be called with or without the global lock held.
7573     */
7574    @Override
7575    public int checkPermission(String permission, int pid, int uid) {
7576        if (permission == null) {
7577            return PackageManager.PERMISSION_DENIED;
7578        }
7579        return checkComponentPermission(permission, pid, uid, -1, true);
7580    }
7581
7582    @Override
7583    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7584        if (permission == null) {
7585            return PackageManager.PERMISSION_DENIED;
7586        }
7587
7588        // We might be performing an operation on behalf of an indirect binder
7589        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7590        // client identity accordingly before proceeding.
7591        Identity tlsIdentity = sCallerIdentity.get();
7592        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7593            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7594                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7595            uid = tlsIdentity.uid;
7596            pid = tlsIdentity.pid;
7597        }
7598
7599        return checkComponentPermission(permission, pid, uid, -1, true);
7600    }
7601
7602    /**
7603     * Binder IPC calls go through the public entry point.
7604     * This can be called with or without the global lock held.
7605     */
7606    int checkCallingPermission(String permission) {
7607        return checkPermission(permission,
7608                Binder.getCallingPid(),
7609                UserHandle.getAppId(Binder.getCallingUid()));
7610    }
7611
7612    /**
7613     * This can be called with or without the global lock held.
7614     */
7615    void enforceCallingPermission(String permission, String func) {
7616        if (checkCallingPermission(permission)
7617                == PackageManager.PERMISSION_GRANTED) {
7618            return;
7619        }
7620
7621        String msg = "Permission Denial: " + func + " from pid="
7622                + Binder.getCallingPid()
7623                + ", uid=" + Binder.getCallingUid()
7624                + " requires " + permission;
7625        Slog.w(TAG, msg);
7626        throw new SecurityException(msg);
7627    }
7628
7629    /**
7630     * Determine if UID is holding permissions required to access {@link Uri} in
7631     * the given {@link ProviderInfo}. Final permission checking is always done
7632     * in {@link ContentProvider}.
7633     */
7634    private final boolean checkHoldingPermissionsLocked(
7635            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7636        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7637                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7638        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7639            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7640                    != PERMISSION_GRANTED) {
7641                return false;
7642            }
7643        }
7644        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7645    }
7646
7647    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7648            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7649        if (pi.applicationInfo.uid == uid) {
7650            return true;
7651        } else if (!pi.exported) {
7652            return false;
7653        }
7654
7655        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7656        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7657        try {
7658            // check if target holds top-level <provider> permissions
7659            if (!readMet && pi.readPermission != null && considerUidPermissions
7660                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7661                readMet = true;
7662            }
7663            if (!writeMet && pi.writePermission != null && considerUidPermissions
7664                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7665                writeMet = true;
7666            }
7667
7668            // track if unprotected read/write is allowed; any denied
7669            // <path-permission> below removes this ability
7670            boolean allowDefaultRead = pi.readPermission == null;
7671            boolean allowDefaultWrite = pi.writePermission == null;
7672
7673            // check if target holds any <path-permission> that match uri
7674            final PathPermission[] pps = pi.pathPermissions;
7675            if (pps != null) {
7676                final String path = grantUri.uri.getPath();
7677                int i = pps.length;
7678                while (i > 0 && (!readMet || !writeMet)) {
7679                    i--;
7680                    PathPermission pp = pps[i];
7681                    if (pp.match(path)) {
7682                        if (!readMet) {
7683                            final String pprperm = pp.getReadPermission();
7684                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7685                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7686                                    + ": match=" + pp.match(path)
7687                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7688                            if (pprperm != null) {
7689                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7690                                        == PERMISSION_GRANTED) {
7691                                    readMet = true;
7692                                } else {
7693                                    allowDefaultRead = false;
7694                                }
7695                            }
7696                        }
7697                        if (!writeMet) {
7698                            final String ppwperm = pp.getWritePermission();
7699                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7700                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7701                                    + ": match=" + pp.match(path)
7702                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7703                            if (ppwperm != null) {
7704                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7705                                        == PERMISSION_GRANTED) {
7706                                    writeMet = true;
7707                                } else {
7708                                    allowDefaultWrite = false;
7709                                }
7710                            }
7711                        }
7712                    }
7713                }
7714            }
7715
7716            // grant unprotected <provider> read/write, if not blocked by
7717            // <path-permission> above
7718            if (allowDefaultRead) readMet = true;
7719            if (allowDefaultWrite) writeMet = true;
7720
7721        } catch (RemoteException e) {
7722            return false;
7723        }
7724
7725        return readMet && writeMet;
7726    }
7727
7728    public int getAppStartMode(int uid, String packageName) {
7729        synchronized (this) {
7730            return checkAllowBackgroundLocked(uid, packageName, -1, true);
7731        }
7732    }
7733
7734    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7735            boolean allowWhenForeground) {
7736        UidRecord uidRec = mActiveUids.get(uid);
7737        if (!mLenientBackgroundCheck) {
7738            if (!allowWhenForeground || uidRec == null
7739                    || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7740                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7741                        packageName) != AppOpsManager.MODE_ALLOWED) {
7742                    return ActivityManager.APP_START_MODE_DELAYED;
7743                }
7744            }
7745
7746        } else if (uidRec == null || uidRec.idle) {
7747            if (callingPid >= 0) {
7748                ProcessRecord proc;
7749                synchronized (mPidsSelfLocked) {
7750                    proc = mPidsSelfLocked.get(callingPid);
7751                }
7752                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7753                    // Whoever is instigating this is in the foreground, so we will allow it
7754                    // to go through.
7755                    return ActivityManager.APP_START_MODE_NORMAL;
7756                }
7757            }
7758            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7759                    != AppOpsManager.MODE_ALLOWED) {
7760                return ActivityManager.APP_START_MODE_DELAYED;
7761            }
7762        }
7763        return ActivityManager.APP_START_MODE_NORMAL;
7764    }
7765
7766    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7767        ProviderInfo pi = null;
7768        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7769        if (cpr != null) {
7770            pi = cpr.info;
7771        } else {
7772            try {
7773                pi = AppGlobals.getPackageManager().resolveContentProvider(
7774                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7775            } catch (RemoteException ex) {
7776            }
7777        }
7778        return pi;
7779    }
7780
7781    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7782        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7783        if (targetUris != null) {
7784            return targetUris.get(grantUri);
7785        }
7786        return null;
7787    }
7788
7789    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7790            String targetPkg, int targetUid, GrantUri grantUri) {
7791        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7792        if (targetUris == null) {
7793            targetUris = Maps.newArrayMap();
7794            mGrantedUriPermissions.put(targetUid, targetUris);
7795        }
7796
7797        UriPermission perm = targetUris.get(grantUri);
7798        if (perm == null) {
7799            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7800            targetUris.put(grantUri, perm);
7801        }
7802
7803        return perm;
7804    }
7805
7806    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7807            final int modeFlags) {
7808        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7809        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7810                : UriPermission.STRENGTH_OWNED;
7811
7812        // Root gets to do everything.
7813        if (uid == 0) {
7814            return true;
7815        }
7816
7817        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7818        if (perms == null) return false;
7819
7820        // First look for exact match
7821        final UriPermission exactPerm = perms.get(grantUri);
7822        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7823            return true;
7824        }
7825
7826        // No exact match, look for prefixes
7827        final int N = perms.size();
7828        for (int i = 0; i < N; i++) {
7829            final UriPermission perm = perms.valueAt(i);
7830            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7831                    && perm.getStrength(modeFlags) >= minStrength) {
7832                return true;
7833            }
7834        }
7835
7836        return false;
7837    }
7838
7839    /**
7840     * @param uri This uri must NOT contain an embedded userId.
7841     * @param userId The userId in which the uri is to be resolved.
7842     */
7843    @Override
7844    public int checkUriPermission(Uri uri, int pid, int uid,
7845            final int modeFlags, int userId, IBinder callerToken) {
7846        enforceNotIsolatedCaller("checkUriPermission");
7847
7848        // Another redirected-binder-call permissions check as in
7849        // {@link checkPermissionWithToken}.
7850        Identity tlsIdentity = sCallerIdentity.get();
7851        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7852            uid = tlsIdentity.uid;
7853            pid = tlsIdentity.pid;
7854        }
7855
7856        // Our own process gets to do everything.
7857        if (pid == MY_PID) {
7858            return PackageManager.PERMISSION_GRANTED;
7859        }
7860        synchronized (this) {
7861            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7862                    ? PackageManager.PERMISSION_GRANTED
7863                    : PackageManager.PERMISSION_DENIED;
7864        }
7865    }
7866
7867    /**
7868     * Check if the targetPkg can be granted permission to access uri by
7869     * the callingUid using the given modeFlags.  Throws a security exception
7870     * if callingUid is not allowed to do this.  Returns the uid of the target
7871     * if the URI permission grant should be performed; returns -1 if it is not
7872     * needed (for example targetPkg already has permission to access the URI).
7873     * If you already know the uid of the target, you can supply it in
7874     * lastTargetUid else set that to -1.
7875     */
7876    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7877            final int modeFlags, int lastTargetUid) {
7878        if (!Intent.isAccessUriMode(modeFlags)) {
7879            return -1;
7880        }
7881
7882        if (targetPkg != null) {
7883            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7884                    "Checking grant " + targetPkg + " permission to " + grantUri);
7885        }
7886
7887        final IPackageManager pm = AppGlobals.getPackageManager();
7888
7889        // If this is not a content: uri, we can't do anything with it.
7890        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7891            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7892                    "Can't grant URI permission for non-content URI: " + grantUri);
7893            return -1;
7894        }
7895
7896        final String authority = grantUri.uri.getAuthority();
7897        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7898        if (pi == null) {
7899            Slog.w(TAG, "No content provider found for permission check: " +
7900                    grantUri.uri.toSafeString());
7901            return -1;
7902        }
7903
7904        int targetUid = lastTargetUid;
7905        if (targetUid < 0 && targetPkg != null) {
7906            try {
7907                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
7908                        UserHandle.getUserId(callingUid));
7909                if (targetUid < 0) {
7910                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7911                            "Can't grant URI permission no uid for: " + targetPkg);
7912                    return -1;
7913                }
7914            } catch (RemoteException ex) {
7915                return -1;
7916            }
7917        }
7918
7919        if (targetUid >= 0) {
7920            // First...  does the target actually need this permission?
7921            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7922                // No need to grant the target this permission.
7923                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7924                        "Target " + targetPkg + " already has full permission to " + grantUri);
7925                return -1;
7926            }
7927        } else {
7928            // First...  there is no target package, so can anyone access it?
7929            boolean allowed = pi.exported;
7930            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7931                if (pi.readPermission != null) {
7932                    allowed = false;
7933                }
7934            }
7935            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7936                if (pi.writePermission != null) {
7937                    allowed = false;
7938                }
7939            }
7940            if (allowed) {
7941                return -1;
7942            }
7943        }
7944
7945        /* There is a special cross user grant if:
7946         * - The target is on another user.
7947         * - Apps on the current user can access the uri without any uid permissions.
7948         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7949         * grant uri permissions.
7950         */
7951        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7952                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7953                modeFlags, false /*without considering the uid permissions*/);
7954
7955        // Second...  is the provider allowing granting of URI permissions?
7956        if (!specialCrossUserGrant) {
7957            if (!pi.grantUriPermissions) {
7958                throw new SecurityException("Provider " + pi.packageName
7959                        + "/" + pi.name
7960                        + " does not allow granting of Uri permissions (uri "
7961                        + grantUri + ")");
7962            }
7963            if (pi.uriPermissionPatterns != null) {
7964                final int N = pi.uriPermissionPatterns.length;
7965                boolean allowed = false;
7966                for (int i=0; i<N; i++) {
7967                    if (pi.uriPermissionPatterns[i] != null
7968                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7969                        allowed = true;
7970                        break;
7971                    }
7972                }
7973                if (!allowed) {
7974                    throw new SecurityException("Provider " + pi.packageName
7975                            + "/" + pi.name
7976                            + " does not allow granting of permission to path of Uri "
7977                            + grantUri);
7978                }
7979            }
7980        }
7981
7982        // Third...  does the caller itself have permission to access
7983        // this uri?
7984        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7985            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7986                // Require they hold a strong enough Uri permission
7987                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7988                    throw new SecurityException("Uid " + callingUid
7989                            + " does not have permission to uri " + grantUri);
7990                }
7991            }
7992        }
7993        return targetUid;
7994    }
7995
7996    /**
7997     * @param uri This uri must NOT contain an embedded userId.
7998     * @param userId The userId in which the uri is to be resolved.
7999     */
8000    @Override
8001    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8002            final int modeFlags, int userId) {
8003        enforceNotIsolatedCaller("checkGrantUriPermission");
8004        synchronized(this) {
8005            return checkGrantUriPermissionLocked(callingUid, targetPkg,
8006                    new GrantUri(userId, uri, false), modeFlags, -1);
8007        }
8008    }
8009
8010    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8011            final int modeFlags, UriPermissionOwner owner) {
8012        if (!Intent.isAccessUriMode(modeFlags)) {
8013            return;
8014        }
8015
8016        // So here we are: the caller has the assumed permission
8017        // to the uri, and the target doesn't.  Let's now give this to
8018        // the target.
8019
8020        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8021                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8022
8023        final String authority = grantUri.uri.getAuthority();
8024        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
8025        if (pi == null) {
8026            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8027            return;
8028        }
8029
8030        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8031            grantUri.prefix = true;
8032        }
8033        final UriPermission perm = findOrCreateUriPermissionLocked(
8034                pi.packageName, targetPkg, targetUid, grantUri);
8035        perm.grantModes(modeFlags, owner);
8036    }
8037
8038    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8039            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8040        if (targetPkg == null) {
8041            throw new NullPointerException("targetPkg");
8042        }
8043        int targetUid;
8044        final IPackageManager pm = AppGlobals.getPackageManager();
8045        try {
8046            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8047        } catch (RemoteException ex) {
8048            return;
8049        }
8050
8051        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8052                targetUid);
8053        if (targetUid < 0) {
8054            return;
8055        }
8056
8057        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8058                owner);
8059    }
8060
8061    static class NeededUriGrants extends ArrayList<GrantUri> {
8062        final String targetPkg;
8063        final int targetUid;
8064        final int flags;
8065
8066        NeededUriGrants(String targetPkg, int targetUid, int flags) {
8067            this.targetPkg = targetPkg;
8068            this.targetUid = targetUid;
8069            this.flags = flags;
8070        }
8071    }
8072
8073    /**
8074     * Like checkGrantUriPermissionLocked, but takes an Intent.
8075     */
8076    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8077            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8078        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8079                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8080                + " clip=" + (intent != null ? intent.getClipData() : null)
8081                + " from " + intent + "; flags=0x"
8082                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8083
8084        if (targetPkg == null) {
8085            throw new NullPointerException("targetPkg");
8086        }
8087
8088        if (intent == null) {
8089            return null;
8090        }
8091        Uri data = intent.getData();
8092        ClipData clip = intent.getClipData();
8093        if (data == null && clip == null) {
8094            return null;
8095        }
8096        // Default userId for uris in the intent (if they don't specify it themselves)
8097        int contentUserHint = intent.getContentUserHint();
8098        if (contentUserHint == UserHandle.USER_CURRENT) {
8099            contentUserHint = UserHandle.getUserId(callingUid);
8100        }
8101        final IPackageManager pm = AppGlobals.getPackageManager();
8102        int targetUid;
8103        if (needed != null) {
8104            targetUid = needed.targetUid;
8105        } else {
8106            try {
8107                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8108                        targetUserId);
8109            } catch (RemoteException ex) {
8110                return null;
8111            }
8112            if (targetUid < 0) {
8113                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8114                        "Can't grant URI permission no uid for: " + targetPkg
8115                        + " on user " + targetUserId);
8116                return null;
8117            }
8118        }
8119        if (data != null) {
8120            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8121            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8122                    targetUid);
8123            if (targetUid > 0) {
8124                if (needed == null) {
8125                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8126                }
8127                needed.add(grantUri);
8128            }
8129        }
8130        if (clip != null) {
8131            for (int i=0; i<clip.getItemCount(); i++) {
8132                Uri uri = clip.getItemAt(i).getUri();
8133                if (uri != null) {
8134                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8135                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8136                            targetUid);
8137                    if (targetUid > 0) {
8138                        if (needed == null) {
8139                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8140                        }
8141                        needed.add(grantUri);
8142                    }
8143                } else {
8144                    Intent clipIntent = clip.getItemAt(i).getIntent();
8145                    if (clipIntent != null) {
8146                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8147                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8148                        if (newNeeded != null) {
8149                            needed = newNeeded;
8150                        }
8151                    }
8152                }
8153            }
8154        }
8155
8156        return needed;
8157    }
8158
8159    /**
8160     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8161     */
8162    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8163            UriPermissionOwner owner) {
8164        if (needed != null) {
8165            for (int i=0; i<needed.size(); i++) {
8166                GrantUri grantUri = needed.get(i);
8167                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8168                        grantUri, needed.flags, owner);
8169            }
8170        }
8171    }
8172
8173    void grantUriPermissionFromIntentLocked(int callingUid,
8174            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8175        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8176                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8177        if (needed == null) {
8178            return;
8179        }
8180
8181        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8182    }
8183
8184    /**
8185     * @param uri This uri must NOT contain an embedded userId.
8186     * @param userId The userId in which the uri is to be resolved.
8187     */
8188    @Override
8189    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8190            final int modeFlags, int userId) {
8191        enforceNotIsolatedCaller("grantUriPermission");
8192        GrantUri grantUri = new GrantUri(userId, uri, false);
8193        synchronized(this) {
8194            final ProcessRecord r = getRecordForAppLocked(caller);
8195            if (r == null) {
8196                throw new SecurityException("Unable to find app for caller "
8197                        + caller
8198                        + " when granting permission to uri " + grantUri);
8199            }
8200            if (targetPkg == null) {
8201                throw new IllegalArgumentException("null target");
8202            }
8203            if (grantUri == null) {
8204                throw new IllegalArgumentException("null uri");
8205            }
8206
8207            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8208                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8209                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8210                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8211
8212            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8213                    UserHandle.getUserId(r.uid));
8214        }
8215    }
8216
8217    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8218        if (perm.modeFlags == 0) {
8219            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8220                    perm.targetUid);
8221            if (perms != null) {
8222                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8223                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8224
8225                perms.remove(perm.uri);
8226                if (perms.isEmpty()) {
8227                    mGrantedUriPermissions.remove(perm.targetUid);
8228                }
8229            }
8230        }
8231    }
8232
8233    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8234        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8235                "Revoking all granted permissions to " + grantUri);
8236
8237        final IPackageManager pm = AppGlobals.getPackageManager();
8238        final String authority = grantUri.uri.getAuthority();
8239        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
8240        if (pi == null) {
8241            Slog.w(TAG, "No content provider found for permission revoke: "
8242                    + grantUri.toSafeString());
8243            return;
8244        }
8245
8246        // Does the caller have this permission on the URI?
8247        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8248            // If they don't have direct access to the URI, then revoke any
8249            // ownerless URI permissions that have been granted to them.
8250            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8251            if (perms != null) {
8252                boolean persistChanged = false;
8253                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8254                    final UriPermission perm = it.next();
8255                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8256                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8257                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8258                                "Revoking non-owned " + perm.targetUid
8259                                + " permission to " + perm.uri);
8260                        persistChanged |= perm.revokeModes(
8261                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8262                        if (perm.modeFlags == 0) {
8263                            it.remove();
8264                        }
8265                    }
8266                }
8267                if (perms.isEmpty()) {
8268                    mGrantedUriPermissions.remove(callingUid);
8269                }
8270                if (persistChanged) {
8271                    schedulePersistUriGrants();
8272                }
8273            }
8274            return;
8275        }
8276
8277        boolean persistChanged = false;
8278
8279        // Go through all of the permissions and remove any that match.
8280        int N = mGrantedUriPermissions.size();
8281        for (int i = 0; i < N; i++) {
8282            final int targetUid = mGrantedUriPermissions.keyAt(i);
8283            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8284
8285            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8286                final UriPermission perm = it.next();
8287                if (perm.uri.sourceUserId == grantUri.sourceUserId
8288                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8289                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8290                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8291                    persistChanged |= perm.revokeModes(
8292                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8293                    if (perm.modeFlags == 0) {
8294                        it.remove();
8295                    }
8296                }
8297            }
8298
8299            if (perms.isEmpty()) {
8300                mGrantedUriPermissions.remove(targetUid);
8301                N--;
8302                i--;
8303            }
8304        }
8305
8306        if (persistChanged) {
8307            schedulePersistUriGrants();
8308        }
8309    }
8310
8311    /**
8312     * @param uri This uri must NOT contain an embedded userId.
8313     * @param userId The userId in which the uri is to be resolved.
8314     */
8315    @Override
8316    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8317            int userId) {
8318        enforceNotIsolatedCaller("revokeUriPermission");
8319        synchronized(this) {
8320            final ProcessRecord r = getRecordForAppLocked(caller);
8321            if (r == null) {
8322                throw new SecurityException("Unable to find app for caller "
8323                        + caller
8324                        + " when revoking permission to uri " + uri);
8325            }
8326            if (uri == null) {
8327                Slog.w(TAG, "revokeUriPermission: null uri");
8328                return;
8329            }
8330
8331            if (!Intent.isAccessUriMode(modeFlags)) {
8332                return;
8333            }
8334
8335            final String authority = uri.getAuthority();
8336            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
8337            if (pi == null) {
8338                Slog.w(TAG, "No content provider found for permission revoke: "
8339                        + uri.toSafeString());
8340                return;
8341            }
8342
8343            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8344        }
8345    }
8346
8347    /**
8348     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8349     * given package.
8350     *
8351     * @param packageName Package name to match, or {@code null} to apply to all
8352     *            packages.
8353     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8354     *            to all users.
8355     * @param persistable If persistable grants should be removed.
8356     */
8357    private void removeUriPermissionsForPackageLocked(
8358            String packageName, int userHandle, boolean persistable) {
8359        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8360            throw new IllegalArgumentException("Must narrow by either package or user");
8361        }
8362
8363        boolean persistChanged = false;
8364
8365        int N = mGrantedUriPermissions.size();
8366        for (int i = 0; i < N; i++) {
8367            final int targetUid = mGrantedUriPermissions.keyAt(i);
8368            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8369
8370            // Only inspect grants matching user
8371            if (userHandle == UserHandle.USER_ALL
8372                    || userHandle == UserHandle.getUserId(targetUid)) {
8373                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8374                    final UriPermission perm = it.next();
8375
8376                    // Only inspect grants matching package
8377                    if (packageName == null || perm.sourcePkg.equals(packageName)
8378                            || perm.targetPkg.equals(packageName)) {
8379                        persistChanged |= perm.revokeModes(persistable
8380                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8381
8382                        // Only remove when no modes remain; any persisted grants
8383                        // will keep this alive.
8384                        if (perm.modeFlags == 0) {
8385                            it.remove();
8386                        }
8387                    }
8388                }
8389
8390                if (perms.isEmpty()) {
8391                    mGrantedUriPermissions.remove(targetUid);
8392                    N--;
8393                    i--;
8394                }
8395            }
8396        }
8397
8398        if (persistChanged) {
8399            schedulePersistUriGrants();
8400        }
8401    }
8402
8403    @Override
8404    public IBinder newUriPermissionOwner(String name) {
8405        enforceNotIsolatedCaller("newUriPermissionOwner");
8406        synchronized(this) {
8407            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8408            return owner.getExternalTokenLocked();
8409        }
8410    }
8411
8412    @Override
8413    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8414        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8415        synchronized(this) {
8416            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8417            if (r == null) {
8418                throw new IllegalArgumentException("Activity does not exist; token="
8419                        + activityToken);
8420            }
8421            return r.getUriPermissionsLocked().getExternalTokenLocked();
8422        }
8423    }
8424    /**
8425     * @param uri This uri must NOT contain an embedded userId.
8426     * @param sourceUserId The userId in which the uri is to be resolved.
8427     * @param targetUserId The userId of the app that receives the grant.
8428     */
8429    @Override
8430    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8431            final int modeFlags, int sourceUserId, int targetUserId) {
8432        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8433                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8434                "grantUriPermissionFromOwner", null);
8435        synchronized(this) {
8436            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8437            if (owner == null) {
8438                throw new IllegalArgumentException("Unknown owner: " + token);
8439            }
8440            if (fromUid != Binder.getCallingUid()) {
8441                if (Binder.getCallingUid() != Process.myUid()) {
8442                    // Only system code can grant URI permissions on behalf
8443                    // of other users.
8444                    throw new SecurityException("nice try");
8445                }
8446            }
8447            if (targetPkg == null) {
8448                throw new IllegalArgumentException("null target");
8449            }
8450            if (uri == null) {
8451                throw new IllegalArgumentException("null uri");
8452            }
8453
8454            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8455                    modeFlags, owner, targetUserId);
8456        }
8457    }
8458
8459    /**
8460     * @param uri This uri must NOT contain an embedded userId.
8461     * @param userId The userId in which the uri is to be resolved.
8462     */
8463    @Override
8464    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8465        synchronized(this) {
8466            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8467            if (owner == null) {
8468                throw new IllegalArgumentException("Unknown owner: " + token);
8469            }
8470
8471            if (uri == null) {
8472                owner.removeUriPermissionsLocked(mode);
8473            } else {
8474                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8475            }
8476        }
8477    }
8478
8479    private void schedulePersistUriGrants() {
8480        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8481            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8482                    10 * DateUtils.SECOND_IN_MILLIS);
8483        }
8484    }
8485
8486    private void writeGrantedUriPermissions() {
8487        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8488
8489        // Snapshot permissions so we can persist without lock
8490        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8491        synchronized (this) {
8492            final int size = mGrantedUriPermissions.size();
8493            for (int i = 0; i < size; i++) {
8494                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8495                for (UriPermission perm : perms.values()) {
8496                    if (perm.persistedModeFlags != 0) {
8497                        persist.add(perm.snapshot());
8498                    }
8499                }
8500            }
8501        }
8502
8503        FileOutputStream fos = null;
8504        try {
8505            fos = mGrantFile.startWrite();
8506
8507            XmlSerializer out = new FastXmlSerializer();
8508            out.setOutput(fos, StandardCharsets.UTF_8.name());
8509            out.startDocument(null, true);
8510            out.startTag(null, TAG_URI_GRANTS);
8511            for (UriPermission.Snapshot perm : persist) {
8512                out.startTag(null, TAG_URI_GRANT);
8513                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8514                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8515                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8516                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8517                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8518                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8519                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8520                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8521                out.endTag(null, TAG_URI_GRANT);
8522            }
8523            out.endTag(null, TAG_URI_GRANTS);
8524            out.endDocument();
8525
8526            mGrantFile.finishWrite(fos);
8527        } catch (IOException e) {
8528            if (fos != null) {
8529                mGrantFile.failWrite(fos);
8530            }
8531        }
8532    }
8533
8534    private void readGrantedUriPermissionsLocked() {
8535        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8536
8537        final long now = System.currentTimeMillis();
8538
8539        FileInputStream fis = null;
8540        try {
8541            fis = mGrantFile.openRead();
8542            final XmlPullParser in = Xml.newPullParser();
8543            in.setInput(fis, StandardCharsets.UTF_8.name());
8544
8545            int type;
8546            while ((type = in.next()) != END_DOCUMENT) {
8547                final String tag = in.getName();
8548                if (type == START_TAG) {
8549                    if (TAG_URI_GRANT.equals(tag)) {
8550                        final int sourceUserId;
8551                        final int targetUserId;
8552                        final int userHandle = readIntAttribute(in,
8553                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8554                        if (userHandle != UserHandle.USER_NULL) {
8555                            // For backwards compatibility.
8556                            sourceUserId = userHandle;
8557                            targetUserId = userHandle;
8558                        } else {
8559                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8560                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8561                        }
8562                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8563                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8564                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8565                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8566                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8567                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8568
8569                        // Sanity check that provider still belongs to source package
8570                        final ProviderInfo pi = getProviderInfoLocked(
8571                                uri.getAuthority(), sourceUserId);
8572                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8573                            int targetUid = -1;
8574                            try {
8575                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8576                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8577                            } catch (RemoteException e) {
8578                            }
8579                            if (targetUid != -1) {
8580                                final UriPermission perm = findOrCreateUriPermissionLocked(
8581                                        sourcePkg, targetPkg, targetUid,
8582                                        new GrantUri(sourceUserId, uri, prefix));
8583                                perm.initPersistedModes(modeFlags, createdTime);
8584                            }
8585                        } else {
8586                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8587                                    + " but instead found " + pi);
8588                        }
8589                    }
8590                }
8591            }
8592        } catch (FileNotFoundException e) {
8593            // Missing grants is okay
8594        } catch (IOException e) {
8595            Slog.wtf(TAG, "Failed reading Uri grants", e);
8596        } catch (XmlPullParserException e) {
8597            Slog.wtf(TAG, "Failed reading Uri grants", e);
8598        } finally {
8599            IoUtils.closeQuietly(fis);
8600        }
8601    }
8602
8603    /**
8604     * @param uri This uri must NOT contain an embedded userId.
8605     * @param userId The userId in which the uri is to be resolved.
8606     */
8607    @Override
8608    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8609        enforceNotIsolatedCaller("takePersistableUriPermission");
8610
8611        Preconditions.checkFlagsArgument(modeFlags,
8612                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8613
8614        synchronized (this) {
8615            final int callingUid = Binder.getCallingUid();
8616            boolean persistChanged = false;
8617            GrantUri grantUri = new GrantUri(userId, uri, false);
8618
8619            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8620                    new GrantUri(userId, uri, false));
8621            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8622                    new GrantUri(userId, uri, true));
8623
8624            final boolean exactValid = (exactPerm != null)
8625                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8626            final boolean prefixValid = (prefixPerm != null)
8627                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8628
8629            if (!(exactValid || prefixValid)) {
8630                throw new SecurityException("No persistable permission grants found for UID "
8631                        + callingUid + " and Uri " + grantUri.toSafeString());
8632            }
8633
8634            if (exactValid) {
8635                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8636            }
8637            if (prefixValid) {
8638                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8639            }
8640
8641            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8642
8643            if (persistChanged) {
8644                schedulePersistUriGrants();
8645            }
8646        }
8647    }
8648
8649    /**
8650     * @param uri This uri must NOT contain an embedded userId.
8651     * @param userId The userId in which the uri is to be resolved.
8652     */
8653    @Override
8654    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8655        enforceNotIsolatedCaller("releasePersistableUriPermission");
8656
8657        Preconditions.checkFlagsArgument(modeFlags,
8658                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8659
8660        synchronized (this) {
8661            final int callingUid = Binder.getCallingUid();
8662            boolean persistChanged = false;
8663
8664            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8665                    new GrantUri(userId, uri, false));
8666            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8667                    new GrantUri(userId, uri, true));
8668            if (exactPerm == null && prefixPerm == null) {
8669                throw new SecurityException("No permission grants found for UID " + callingUid
8670                        + " and Uri " + uri.toSafeString());
8671            }
8672
8673            if (exactPerm != null) {
8674                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8675                removeUriPermissionIfNeededLocked(exactPerm);
8676            }
8677            if (prefixPerm != null) {
8678                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8679                removeUriPermissionIfNeededLocked(prefixPerm);
8680            }
8681
8682            if (persistChanged) {
8683                schedulePersistUriGrants();
8684            }
8685        }
8686    }
8687
8688    /**
8689     * Prune any older {@link UriPermission} for the given UID until outstanding
8690     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8691     *
8692     * @return if any mutations occured that require persisting.
8693     */
8694    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8695        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8696        if (perms == null) return false;
8697        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8698
8699        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8700        for (UriPermission perm : perms.values()) {
8701            if (perm.persistedModeFlags != 0) {
8702                persisted.add(perm);
8703            }
8704        }
8705
8706        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8707        if (trimCount <= 0) return false;
8708
8709        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8710        for (int i = 0; i < trimCount; i++) {
8711            final UriPermission perm = persisted.get(i);
8712
8713            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8714                    "Trimming grant created at " + perm.persistedCreateTime);
8715
8716            perm.releasePersistableModes(~0);
8717            removeUriPermissionIfNeededLocked(perm);
8718        }
8719
8720        return true;
8721    }
8722
8723    @Override
8724    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8725            String packageName, boolean incoming) {
8726        enforceNotIsolatedCaller("getPersistedUriPermissions");
8727        Preconditions.checkNotNull(packageName, "packageName");
8728
8729        final int callingUid = Binder.getCallingUid();
8730        final IPackageManager pm = AppGlobals.getPackageManager();
8731        try {
8732            final int packageUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
8733                    UserHandle.getUserId(callingUid));
8734            if (packageUid != callingUid) {
8735                throw new SecurityException(
8736                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8737            }
8738        } catch (RemoteException e) {
8739            throw new SecurityException("Failed to verify package name ownership");
8740        }
8741
8742        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8743        synchronized (this) {
8744            if (incoming) {
8745                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8746                        callingUid);
8747                if (perms == null) {
8748                    Slog.w(TAG, "No permission grants found for " + packageName);
8749                } else {
8750                    for (UriPermission perm : perms.values()) {
8751                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8752                            result.add(perm.buildPersistedPublicApiObject());
8753                        }
8754                    }
8755                }
8756            } else {
8757                final int size = mGrantedUriPermissions.size();
8758                for (int i = 0; i < size; i++) {
8759                    final ArrayMap<GrantUri, UriPermission> perms =
8760                            mGrantedUriPermissions.valueAt(i);
8761                    for (UriPermission perm : perms.values()) {
8762                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8763                            result.add(perm.buildPersistedPublicApiObject());
8764                        }
8765                    }
8766                }
8767            }
8768        }
8769        return new ParceledListSlice<android.content.UriPermission>(result);
8770    }
8771
8772    @Override
8773    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8774            String packageName, int userId) {
8775        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8776                "getGrantedUriPermissions");
8777
8778        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8779        synchronized (this) {
8780            final int size = mGrantedUriPermissions.size();
8781            for (int i = 0; i < size; i++) {
8782                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8783                for (UriPermission perm : perms.values()) {
8784                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8785                            && perm.persistedModeFlags != 0) {
8786                        result.add(perm.buildPersistedPublicApiObject());
8787                    }
8788                }
8789            }
8790        }
8791        return new ParceledListSlice<android.content.UriPermission>(result);
8792    }
8793
8794    @Override
8795    public void clearGrantedUriPermissions(String packageName, int userId) {
8796        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8797                "clearGrantedUriPermissions");
8798        removeUriPermissionsForPackageLocked(packageName, userId, true);
8799    }
8800
8801    @Override
8802    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8803        synchronized (this) {
8804            ProcessRecord app =
8805                who != null ? getRecordForAppLocked(who) : null;
8806            if (app == null) return;
8807
8808            Message msg = Message.obtain();
8809            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8810            msg.obj = app;
8811            msg.arg1 = waiting ? 1 : 0;
8812            mUiHandler.sendMessage(msg);
8813        }
8814    }
8815
8816    @Override
8817    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8818        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8819        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8820        outInfo.availMem = Process.getFreeMemory();
8821        outInfo.totalMem = Process.getTotalMemory();
8822        outInfo.threshold = homeAppMem;
8823        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8824        outInfo.hiddenAppThreshold = cachedAppMem;
8825        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8826                ProcessList.SERVICE_ADJ);
8827        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8828                ProcessList.VISIBLE_APP_ADJ);
8829        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8830                ProcessList.FOREGROUND_APP_ADJ);
8831    }
8832
8833    // =========================================================
8834    // TASK MANAGEMENT
8835    // =========================================================
8836
8837    @Override
8838    public List<IAppTask> getAppTasks(String callingPackage) {
8839        int callingUid = Binder.getCallingUid();
8840        long ident = Binder.clearCallingIdentity();
8841
8842        synchronized(this) {
8843            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8844            try {
8845                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8846
8847                final int N = mRecentTasks.size();
8848                for (int i = 0; i < N; i++) {
8849                    TaskRecord tr = mRecentTasks.get(i);
8850                    // Skip tasks that do not match the caller.  We don't need to verify
8851                    // callingPackage, because we are also limiting to callingUid and know
8852                    // that will limit to the correct security sandbox.
8853                    if (tr.effectiveUid != callingUid) {
8854                        continue;
8855                    }
8856                    Intent intent = tr.getBaseIntent();
8857                    if (intent == null ||
8858                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8859                        continue;
8860                    }
8861                    ActivityManager.RecentTaskInfo taskInfo =
8862                            createRecentTaskInfoFromTaskRecord(tr);
8863                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8864                    list.add(taskImpl);
8865                }
8866            } finally {
8867                Binder.restoreCallingIdentity(ident);
8868            }
8869            return list;
8870        }
8871    }
8872
8873    @Override
8874    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8875        final int callingUid = Binder.getCallingUid();
8876        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8877
8878        synchronized(this) {
8879            if (DEBUG_ALL) Slog.v(
8880                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8881
8882            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8883                    callingUid);
8884
8885            // TODO: Improve with MRU list from all ActivityStacks.
8886            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8887        }
8888
8889        return list;
8890    }
8891
8892    /**
8893     * Creates a new RecentTaskInfo from a TaskRecord.
8894     */
8895    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8896        // Update the task description to reflect any changes in the task stack
8897        tr.updateTaskDescription();
8898
8899        // Compose the recent task info
8900        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8901        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8902        rti.persistentId = tr.taskId;
8903        rti.baseIntent = new Intent(tr.getBaseIntent());
8904        rti.origActivity = tr.origActivity;
8905        rti.realActivity = tr.realActivity;
8906        rti.description = tr.lastDescription;
8907        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8908        rti.userId = tr.userId;
8909        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8910        rti.firstActiveTime = tr.firstActiveTime;
8911        rti.lastActiveTime = tr.lastActiveTime;
8912        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8913        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8914        rti.numActivities = 0;
8915        if (tr.mBounds != null) {
8916            rti.bounds = new Rect(tr.mBounds);
8917        }
8918        rti.isDockable = tr.canGoInDockedStack();
8919        rti.resizeMode = tr.mResizeMode;
8920
8921        ActivityRecord base = null;
8922        ActivityRecord top = null;
8923        ActivityRecord tmp;
8924
8925        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8926            tmp = tr.mActivities.get(i);
8927            if (tmp.finishing) {
8928                continue;
8929            }
8930            base = tmp;
8931            if (top == null || (top.state == ActivityState.INITIALIZING)) {
8932                top = base;
8933            }
8934            rti.numActivities++;
8935        }
8936
8937        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8938        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8939
8940        return rti;
8941    }
8942
8943    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8944        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8945                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8946        if (!allowed) {
8947            if (checkPermission(android.Manifest.permission.GET_TASKS,
8948                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8949                // Temporary compatibility: some existing apps on the system image may
8950                // still be requesting the old permission and not switched to the new
8951                // one; if so, we'll still allow them full access.  This means we need
8952                // to see if they are holding the old permission and are a system app.
8953                try {
8954                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8955                        allowed = true;
8956                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8957                                + " is using old GET_TASKS but privileged; allowing");
8958                    }
8959                } catch (RemoteException e) {
8960                }
8961            }
8962        }
8963        if (!allowed) {
8964            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8965                    + " does not hold REAL_GET_TASKS; limiting output");
8966        }
8967        return allowed;
8968    }
8969
8970    @Override
8971    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8972        final int callingUid = Binder.getCallingUid();
8973        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8974                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8975
8976        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8977        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8978        synchronized (this) {
8979            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8980                    callingUid);
8981            final boolean detailed = checkCallingPermission(
8982                    android.Manifest.permission.GET_DETAILED_TASKS)
8983                    == PackageManager.PERMISSION_GRANTED;
8984
8985            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
8986                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
8987                return Collections.emptyList();
8988            }
8989            mRecentTasks.loadUserRecentsLocked(userId);
8990
8991            final int recentsCount = mRecentTasks.size();
8992            ArrayList<ActivityManager.RecentTaskInfo> res =
8993                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
8994
8995            final Set<Integer> includedUsers;
8996            if (includeProfiles) {
8997                includedUsers = mUserController.getProfileIds(userId);
8998            } else {
8999                includedUsers = new HashSet<>();
9000            }
9001            includedUsers.add(Integer.valueOf(userId));
9002
9003            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9004                TaskRecord tr = mRecentTasks.get(i);
9005                // Only add calling user or related users recent tasks
9006                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9007                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9008                    continue;
9009                }
9010
9011                if (tr.realActivitySuspended) {
9012                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9013                    continue;
9014                }
9015
9016                // Return the entry if desired by the caller.  We always return
9017                // the first entry, because callers always expect this to be the
9018                // foreground app.  We may filter others if the caller has
9019                // not supplied RECENT_WITH_EXCLUDED and there is some reason
9020                // we should exclude the entry.
9021
9022                if (i == 0
9023                        || withExcluded
9024                        || (tr.intent == null)
9025                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9026                                == 0)) {
9027                    if (!allowed) {
9028                        // If the caller doesn't have the GET_TASKS permission, then only
9029                        // allow them to see a small subset of tasks -- their own and home.
9030                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9031                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9032                            continue;
9033                        }
9034                    }
9035                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
9036                        if (tr.stack != null && tr.stack.isHomeStack()) {
9037                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9038                                    "Skipping, home stack task: " + tr);
9039                            continue;
9040                        }
9041                    }
9042                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9043                        final ActivityStack stack = tr.stack;
9044                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9045                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9046                                    "Skipping, top task in docked stack: " + tr);
9047                            continue;
9048                        }
9049                    }
9050                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9051                        if (tr.stack != null && tr.stack.isPinnedStack()) {
9052                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9053                                    "Skipping, pinned stack task: " + tr);
9054                            continue;
9055                        }
9056                    }
9057                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9058                        // Don't include auto remove tasks that are finished or finishing.
9059                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9060                                "Skipping, auto-remove without activity: " + tr);
9061                        continue;
9062                    }
9063                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9064                            && !tr.isAvailable) {
9065                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9066                                "Skipping, unavail real act: " + tr);
9067                        continue;
9068                    }
9069
9070                    if (!tr.mUserSetupComplete) {
9071                        // Don't include task launched while user is not done setting-up.
9072                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9073                                "Skipping, user setup not complete: " + tr);
9074                        continue;
9075                    }
9076
9077                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9078                    if (!detailed) {
9079                        rti.baseIntent.replaceExtras((Bundle)null);
9080                    }
9081
9082                    res.add(rti);
9083                    maxNum--;
9084                }
9085            }
9086            return res;
9087        }
9088    }
9089
9090    @Override
9091    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9092        synchronized (this) {
9093            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9094                    "getTaskThumbnail()");
9095            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9096                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9097            if (tr != null) {
9098                return tr.getTaskThumbnailLocked();
9099            }
9100        }
9101        return null;
9102    }
9103
9104    @Override
9105    public int addAppTask(IBinder activityToken, Intent intent,
9106            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9107        final int callingUid = Binder.getCallingUid();
9108        final long callingIdent = Binder.clearCallingIdentity();
9109
9110        try {
9111            synchronized (this) {
9112                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9113                if (r == null) {
9114                    throw new IllegalArgumentException("Activity does not exist; token="
9115                            + activityToken);
9116                }
9117                ComponentName comp = intent.getComponent();
9118                if (comp == null) {
9119                    throw new IllegalArgumentException("Intent " + intent
9120                            + " must specify explicit component");
9121                }
9122                if (thumbnail.getWidth() != mThumbnailWidth
9123                        || thumbnail.getHeight() != mThumbnailHeight) {
9124                    throw new IllegalArgumentException("Bad thumbnail size: got "
9125                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9126                            + mThumbnailWidth + "x" + mThumbnailHeight);
9127                }
9128                if (intent.getSelector() != null) {
9129                    intent.setSelector(null);
9130                }
9131                if (intent.getSourceBounds() != null) {
9132                    intent.setSourceBounds(null);
9133                }
9134                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9135                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9136                        // The caller has added this as an auto-remove task...  that makes no
9137                        // sense, so turn off auto-remove.
9138                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9139                    }
9140                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
9141                    // Must be a new task.
9142                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
9143                }
9144                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9145                    mLastAddedTaskActivity = null;
9146                }
9147                ActivityInfo ainfo = mLastAddedTaskActivity;
9148                if (ainfo == null) {
9149                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9150                            comp, 0, UserHandle.getUserId(callingUid));
9151                    if (ainfo.applicationInfo.uid != callingUid) {
9152                        throw new SecurityException(
9153                                "Can't add task for another application: target uid="
9154                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9155                    }
9156                }
9157
9158                // Use the full screen as the context for the task thumbnail
9159                final Point displaySize = new Point();
9160                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9161                r.task.stack.getDisplaySize(displaySize);
9162                thumbnailInfo.taskWidth = displaySize.x;
9163                thumbnailInfo.taskHeight = displaySize.y;
9164                thumbnailInfo.screenOrientation = mConfiguration.orientation;
9165
9166                TaskRecord task = new TaskRecord(this,
9167                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9168                        ainfo, intent, description, thumbnailInfo);
9169
9170                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9171                if (trimIdx >= 0) {
9172                    // If this would have caused a trim, then we'll abort because that
9173                    // means it would be added at the end of the list but then just removed.
9174                    return INVALID_TASK_ID;
9175                }
9176
9177                final int N = mRecentTasks.size();
9178                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9179                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9180                    tr.removedFromRecents();
9181                }
9182
9183                task.inRecents = true;
9184                mRecentTasks.add(task);
9185                r.task.stack.addTask(task, false, "addAppTask");
9186
9187                task.setLastThumbnailLocked(thumbnail);
9188                task.freeLastThumbnail();
9189
9190                return task.taskId;
9191            }
9192        } finally {
9193            Binder.restoreCallingIdentity(callingIdent);
9194        }
9195    }
9196
9197    @Override
9198    public Point getAppTaskThumbnailSize() {
9199        synchronized (this) {
9200            return new Point(mThumbnailWidth,  mThumbnailHeight);
9201        }
9202    }
9203
9204    @Override
9205    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9206        synchronized (this) {
9207            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9208            if (r != null) {
9209                r.setTaskDescription(td);
9210                r.task.updateTaskDescription();
9211            }
9212        }
9213    }
9214
9215    @Override
9216    public void setTaskResizeable(int taskId, int resizeableMode) {
9217        synchronized (this) {
9218            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9219                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9220            if (task == null) {
9221                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9222                return;
9223            }
9224            if (task.mResizeMode != resizeableMode) {
9225                task.mResizeMode = resizeableMode;
9226                mWindowManager.setTaskResizeable(taskId, resizeableMode);
9227                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9228                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9229            }
9230        }
9231    }
9232
9233    @Override
9234    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9235        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9236        long ident = Binder.clearCallingIdentity();
9237        try {
9238            synchronized (this) {
9239                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9240                if (task == null) {
9241                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9242                    return;
9243                }
9244                int stackId = task.stack.mStackId;
9245                // We allow the task to scroll instead of resizing if this is a non-resizeable task
9246                // in crop windows resize mode or if the task size is affected by the docked stack
9247                // changing size. No need to update configuration.
9248                if (bounds != null && task.inCropWindowsResizeMode()
9249                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
9250                    mWindowManager.scrollTask(task.taskId, bounds);
9251                    return;
9252                }
9253
9254                // Place the task in the right stack if it isn't there already based on
9255                // the requested bounds.
9256                // The stack transition logic is:
9257                // - a null bounds on a freeform task moves that task to fullscreen
9258                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9259                //   that task to freeform
9260                // - otherwise the task is not moved
9261                if (!StackId.isTaskResizeAllowed(stackId)) {
9262                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9263                }
9264                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9265                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9266                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9267                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9268                }
9269                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9270                if (stackId != task.stack.mStackId) {
9271                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9272                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9273                    preserveWindow = false;
9274                }
9275
9276                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9277                        false /* deferResume */);
9278            }
9279        } finally {
9280            Binder.restoreCallingIdentity(ident);
9281        }
9282    }
9283
9284    @Override
9285    public Rect getTaskBounds(int taskId) {
9286        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9287        long ident = Binder.clearCallingIdentity();
9288        Rect rect = new Rect();
9289        try {
9290            synchronized (this) {
9291                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9292                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9293                if (task == null) {
9294                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9295                    return rect;
9296                }
9297                if (task.stack != null) {
9298                    // Return the bounds from window manager since it will be adjusted for various
9299                    // things like the presense of a docked stack for tasks that aren't resizeable.
9300                    mWindowManager.getTaskBounds(task.taskId, rect);
9301                } else {
9302                    // Task isn't in window manager yet since it isn't associated with a stack.
9303                    // Return the persist value from activity manager
9304                    if (task.mBounds != null) {
9305                        rect.set(task.mBounds);
9306                    } else if (task.mLastNonFullscreenBounds != null) {
9307                        rect.set(task.mLastNonFullscreenBounds);
9308                    }
9309                }
9310            }
9311        } finally {
9312            Binder.restoreCallingIdentity(ident);
9313        }
9314        return rect;
9315    }
9316
9317    @Override
9318    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9319        if (userId != UserHandle.getCallingUserId()) {
9320            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9321                    "getTaskDescriptionIcon");
9322        }
9323        final File passedIconFile = new File(filePath);
9324        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9325                passedIconFile.getName());
9326        if (!legitIconFile.getPath().equals(filePath)
9327                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9328            throw new IllegalArgumentException("Bad file path: " + filePath
9329                    + " passed for userId " + userId);
9330        }
9331        return mRecentTasks.getTaskDescriptionIcon(filePath);
9332    }
9333
9334    @Override
9335    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9336            throws RemoteException {
9337        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9338                opts.getCustomInPlaceResId() == 0) {
9339            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9340                    "with valid animation");
9341        }
9342        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9343        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9344                opts.getCustomInPlaceResId());
9345        mWindowManager.executeAppTransition();
9346    }
9347
9348    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9349            boolean removeFromRecents) {
9350        if (removeFromRecents) {
9351            mRecentTasks.remove(tr);
9352            tr.removedFromRecents();
9353        }
9354        ComponentName component = tr.getBaseIntent().getComponent();
9355        if (component == null) {
9356            Slog.w(TAG, "No component for base intent of task: " + tr);
9357            return;
9358        }
9359
9360        // Find any running services associated with this app and stop if needed.
9361        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9362
9363        if (!killProcess) {
9364            return;
9365        }
9366
9367        // Determine if the process(es) for this task should be killed.
9368        final String pkg = component.getPackageName();
9369        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9370        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9371        for (int i = 0; i < pmap.size(); i++) {
9372
9373            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9374            for (int j = 0; j < uids.size(); j++) {
9375                ProcessRecord proc = uids.valueAt(j);
9376                if (proc.userId != tr.userId) {
9377                    // Don't kill process for a different user.
9378                    continue;
9379                }
9380                if (proc == mHomeProcess) {
9381                    // Don't kill the home process along with tasks from the same package.
9382                    continue;
9383                }
9384                if (!proc.pkgList.containsKey(pkg)) {
9385                    // Don't kill process that is not associated with this task.
9386                    continue;
9387                }
9388
9389                for (int k = 0; k < proc.activities.size(); k++) {
9390                    TaskRecord otherTask = proc.activities.get(k).task;
9391                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9392                        // Don't kill process(es) that has an activity in a different task that is
9393                        // also in recents.
9394                        return;
9395                    }
9396                }
9397
9398                if (proc.foregroundServices) {
9399                    // Don't kill process(es) with foreground service.
9400                    return;
9401                }
9402
9403                // Add process to kill list.
9404                procsToKill.add(proc);
9405            }
9406        }
9407
9408        // Kill the running processes.
9409        for (int i = 0; i < procsToKill.size(); i++) {
9410            ProcessRecord pr = procsToKill.get(i);
9411            if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9412                    && pr.curReceiver == null) {
9413                pr.kill("remove task", true);
9414            } else {
9415                // We delay killing processes that are not in the background or running a receiver.
9416                pr.waitingToKill = "remove task";
9417            }
9418        }
9419    }
9420
9421    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9422        // Remove all tasks with activities in the specified package from the list of recent tasks
9423        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9424            TaskRecord tr = mRecentTasks.get(i);
9425            if (tr.userId != userId) continue;
9426
9427            ComponentName cn = tr.intent.getComponent();
9428            if (cn != null && cn.getPackageName().equals(packageName)) {
9429                // If the package name matches, remove the task.
9430                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9431            }
9432        }
9433    }
9434
9435    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9436            int userId) {
9437
9438        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9439            TaskRecord tr = mRecentTasks.get(i);
9440            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9441                continue;
9442            }
9443
9444            ComponentName cn = tr.intent.getComponent();
9445            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9446                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9447            if (sameComponent) {
9448                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9449            }
9450        }
9451    }
9452
9453    /**
9454     * Removes the task with the specified task id.
9455     *
9456     * @param taskId Identifier of the task to be removed.
9457     * @param killProcess Kill any process associated with the task if possible.
9458     * @param removeFromRecents Whether to also remove the task from recents.
9459     * @return Returns true if the given task was found and removed.
9460     */
9461    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9462            boolean removeFromRecents) {
9463        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9464                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9465        if (tr != null) {
9466            tr.removeTaskActivitiesLocked();
9467            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9468            if (tr.isPersistable) {
9469                notifyTaskPersisterLocked(null, true);
9470            }
9471            return true;
9472        }
9473        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9474        return false;
9475    }
9476
9477    @Override
9478    public void removeStack(int stackId) {
9479        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9480        if (stackId == HOME_STACK_ID) {
9481            throw new IllegalArgumentException("Removing home stack is not allowed.");
9482        }
9483
9484        synchronized (this) {
9485            final long ident = Binder.clearCallingIdentity();
9486            try {
9487                final ActivityStack stack = mStackSupervisor.getStack(stackId);
9488                if (stack == null) {
9489                    return;
9490                }
9491                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9492                for (int i = tasks.size() - 1; i >= 0; i--) {
9493                    removeTaskByIdLocked(
9494                            tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9495                }
9496            } finally {
9497                Binder.restoreCallingIdentity(ident);
9498            }
9499        }
9500    }
9501
9502    @Override
9503    public boolean removeTask(int taskId) {
9504        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9505        synchronized (this) {
9506            final long ident = Binder.clearCallingIdentity();
9507            try {
9508                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9509            } finally {
9510                Binder.restoreCallingIdentity(ident);
9511            }
9512        }
9513    }
9514
9515    /**
9516     * TODO: Add mController hook
9517     */
9518    @Override
9519    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9520        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9521
9522        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9523        synchronized(this) {
9524            moveTaskToFrontLocked(taskId, flags, bOptions);
9525        }
9526    }
9527
9528    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9529        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9530
9531        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9532                Binder.getCallingUid(), -1, -1, "Task to front")) {
9533            ActivityOptions.abort(options);
9534            return;
9535        }
9536        final long origId = Binder.clearCallingIdentity();
9537        try {
9538            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9539            if (task == null) {
9540                Slog.d(TAG, "Could not find task for id: "+ taskId);
9541                return;
9542            }
9543            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9544                mStackSupervisor.showLockTaskToast();
9545                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9546                return;
9547            }
9548            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9549            if (prev != null && prev.isRecentsActivity()) {
9550                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9551            }
9552            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9553                    false /* forceNonResizable */);
9554        } finally {
9555            Binder.restoreCallingIdentity(origId);
9556        }
9557        ActivityOptions.abort(options);
9558    }
9559
9560    /**
9561     * Moves an activity, and all of the other activities within the same task, to the bottom
9562     * of the history stack.  The activity's order within the task is unchanged.
9563     *
9564     * @param token A reference to the activity we wish to move
9565     * @param nonRoot If false then this only works if the activity is the root
9566     *                of a task; if true it will work for any activity in a task.
9567     * @return Returns true if the move completed, false if not.
9568     */
9569    @Override
9570    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9571        enforceNotIsolatedCaller("moveActivityTaskToBack");
9572        synchronized(this) {
9573            final long origId = Binder.clearCallingIdentity();
9574            try {
9575                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9576                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9577                if (task != null) {
9578                    if (mStackSupervisor.isLockedTask(task)) {
9579                        mStackSupervisor.showLockTaskToast();
9580                        return false;
9581                    }
9582                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9583                }
9584            } finally {
9585                Binder.restoreCallingIdentity(origId);
9586            }
9587        }
9588        return false;
9589    }
9590
9591    @Override
9592    public void moveTaskBackwards(int task) {
9593        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9594                "moveTaskBackwards()");
9595
9596        synchronized(this) {
9597            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9598                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9599                return;
9600            }
9601            final long origId = Binder.clearCallingIdentity();
9602            moveTaskBackwardsLocked(task);
9603            Binder.restoreCallingIdentity(origId);
9604        }
9605    }
9606
9607    private final void moveTaskBackwardsLocked(int task) {
9608        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9609    }
9610
9611    @Override
9612    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9613            IActivityContainerCallback callback) throws RemoteException {
9614        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9615        synchronized (this) {
9616            if (parentActivityToken == null) {
9617                throw new IllegalArgumentException("parent token must not be null");
9618            }
9619            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9620            if (r == null) {
9621                return null;
9622            }
9623            if (callback == null) {
9624                throw new IllegalArgumentException("callback must not be null");
9625            }
9626            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9627        }
9628    }
9629
9630    @Override
9631    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9632        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9633        synchronized (this) {
9634            mStackSupervisor.deleteActivityContainer(container);
9635        }
9636    }
9637
9638    @Override
9639    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9640        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9641        synchronized (this) {
9642            final int stackId = mStackSupervisor.getNextStackId();
9643            final ActivityStack stack =
9644                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9645            if (stack == null) {
9646                return null;
9647            }
9648            return stack.mActivityContainer;
9649        }
9650    }
9651
9652    @Override
9653    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9654        synchronized (this) {
9655            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9656            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9657                return stack.mActivityContainer.getDisplayId();
9658            }
9659            return Display.DEFAULT_DISPLAY;
9660        }
9661    }
9662
9663    @Override
9664    public int getActivityStackId(IBinder token) throws RemoteException {
9665        synchronized (this) {
9666            ActivityStack stack = ActivityRecord.getStackLocked(token);
9667            if (stack == null) {
9668                return INVALID_STACK_ID;
9669            }
9670            return stack.mStackId;
9671        }
9672    }
9673
9674    @Override
9675    public void exitFreeformMode(IBinder token) throws RemoteException {
9676        synchronized (this) {
9677            long ident = Binder.clearCallingIdentity();
9678            try {
9679                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9680                if (r == null) {
9681                    throw new IllegalArgumentException(
9682                            "exitFreeformMode: No activity record matching token=" + token);
9683                }
9684                final ActivityStack stack = r.getStackLocked(token);
9685                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9686                    throw new IllegalStateException(
9687                            "exitFreeformMode: You can only go fullscreen from freeform.");
9688                }
9689                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9690                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9691                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9692            } finally {
9693                Binder.restoreCallingIdentity(ident);
9694            }
9695        }
9696    }
9697
9698    @Override
9699    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9700        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9701        if (stackId == HOME_STACK_ID) {
9702            throw new IllegalArgumentException(
9703                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9704        }
9705        synchronized (this) {
9706            long ident = Binder.clearCallingIdentity();
9707            try {
9708                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9709                        + " to stackId=" + stackId + " toTop=" + toTop);
9710                if (stackId == DOCKED_STACK_ID) {
9711                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9712                            null /* initialBounds */);
9713                }
9714                boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9715                        !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9716                if (result && stackId == DOCKED_STACK_ID) {
9717                    // If task moved to docked stack - show recents if needed.
9718                    mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9719                            "moveTaskToDockedStack");
9720                }
9721            } finally {
9722                Binder.restoreCallingIdentity(ident);
9723            }
9724        }
9725    }
9726
9727    @Override
9728    public void swapDockedAndFullscreenStack() throws RemoteException {
9729        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9730        synchronized (this) {
9731            long ident = Binder.clearCallingIdentity();
9732            try {
9733                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9734                        FULLSCREEN_WORKSPACE_STACK_ID);
9735                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9736                        : null;
9737                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9738                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9739                        : null;
9740                if (topTask == null || tasks == null || tasks.size() == 0) {
9741                    Slog.w(TAG,
9742                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
9743                    return;
9744                }
9745
9746                // TODO: App transition
9747                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9748
9749                // Defer the resume so resume/pausing while moving stacks is dangerous.
9750                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9751                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9752                        ANIMATE, true /* deferResume */);
9753                final int size = tasks.size();
9754                for (int i = 0; i < size; i++) {
9755                    final int id = tasks.get(i).taskId;
9756                    if (id == topTask.taskId) {
9757                        continue;
9758                    }
9759                    mStackSupervisor.moveTaskToStackLocked(id,
9760                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9761                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9762                }
9763
9764                // Because we deferred the resume, to avoid conflicts with stack switches while
9765                // resuming, we need to do it after all the tasks are moved.
9766                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9767                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9768
9769                mWindowManager.executeAppTransition();
9770            } finally {
9771                Binder.restoreCallingIdentity(ident);
9772            }
9773        }
9774    }
9775
9776    /**
9777     * Moves the input task to the docked stack.
9778     *
9779     * @param taskId Id of task to move.
9780     * @param createMode The mode the docked stack should be created in if it doesn't exist
9781     *                   already. See
9782     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9783     *                   and
9784     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9785     * @param toTop If the task and stack should be moved to the top.
9786     * @param animate Whether we should play an animation for the moving the task
9787     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9788     *                      docked stack. Pass {@code null} to use default bounds.
9789     */
9790    @Override
9791    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9792            Rect initialBounds, boolean moveHomeStackFront) {
9793        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9794        synchronized (this) {
9795            long ident = Binder.clearCallingIdentity();
9796            try {
9797                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9798                        + " to createMode=" + createMode + " toTop=" + toTop);
9799                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9800                final boolean moved = mStackSupervisor.moveTaskToStackLocked(
9801                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
9802                        animate, DEFER_RESUME);
9803                if (moved) {
9804                    if (moveHomeStackFront) {
9805                        mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
9806                    }
9807                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9808                }
9809                return moved;
9810            } finally {
9811                Binder.restoreCallingIdentity(ident);
9812            }
9813        }
9814    }
9815
9816    /**
9817     * Moves the top activity in the input stackId to the pinned stack.
9818     *
9819     * @param stackId Id of stack to move the top activity to pinned stack.
9820     * @param bounds Bounds to use for pinned stack.
9821     *
9822     * @return True if the top activity of the input stack was successfully moved to the pinned
9823     *          stack.
9824     */
9825    @Override
9826    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9827        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9828        synchronized (this) {
9829            if (!mSupportsPictureInPicture) {
9830                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9831                        + "Device doesn't support picture-in-pciture mode");
9832            }
9833
9834            long ident = Binder.clearCallingIdentity();
9835            try {
9836                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9837            } finally {
9838                Binder.restoreCallingIdentity(ident);
9839            }
9840        }
9841    }
9842
9843    @Override
9844    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9845            boolean preserveWindows, boolean animate, int animationDuration) {
9846        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9847        long ident = Binder.clearCallingIdentity();
9848        try {
9849            synchronized (this) {
9850                if (animate) {
9851                    if (stackId == PINNED_STACK_ID) {
9852                        mWindowManager.animateResizePinnedStack(bounds, animationDuration);
9853                    } else {
9854                        throw new IllegalArgumentException("Stack: " + stackId
9855                                + " doesn't support animated resize.");
9856                    }
9857                } else {
9858                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
9859                            null /* tempTaskInsetBounds */, preserveWindows,
9860                            allowResizeInDockedMode, !DEFER_RESUME);
9861                }
9862            }
9863        } finally {
9864            Binder.restoreCallingIdentity(ident);
9865        }
9866    }
9867
9868    @Override
9869    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
9870            Rect tempDockedTaskInsetBounds,
9871            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
9872        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9873                "resizeDockedStack()");
9874        long ident = Binder.clearCallingIdentity();
9875        try {
9876            synchronized (this) {
9877                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
9878                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
9879                        PRESERVE_WINDOWS);
9880            }
9881        } finally {
9882            Binder.restoreCallingIdentity(ident);
9883        }
9884    }
9885
9886    @Override
9887    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
9888        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9889                "resizePinnedStack()");
9890        final long ident = Binder.clearCallingIdentity();
9891        try {
9892            synchronized (this) {
9893                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
9894            }
9895        } finally {
9896            Binder.restoreCallingIdentity(ident);
9897        }
9898    }
9899
9900    @Override
9901    public void positionTaskInStack(int taskId, int stackId, int position) {
9902        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
9903        if (stackId == HOME_STACK_ID) {
9904            throw new IllegalArgumentException(
9905                    "positionTaskInStack: Attempt to change the position of task "
9906                    + taskId + " in/to home stack");
9907        }
9908        synchronized (this) {
9909            long ident = Binder.clearCallingIdentity();
9910            try {
9911                if (DEBUG_STACK) Slog.d(TAG_STACK,
9912                        "positionTaskInStack: positioning task=" + taskId
9913                        + " in stackId=" + stackId + " at position=" + position);
9914                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
9915            } finally {
9916                Binder.restoreCallingIdentity(ident);
9917            }
9918        }
9919    }
9920
9921    @Override
9922    public List<StackInfo> getAllStackInfos() {
9923        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
9924        long ident = Binder.clearCallingIdentity();
9925        try {
9926            synchronized (this) {
9927                return mStackSupervisor.getAllStackInfosLocked();
9928            }
9929        } finally {
9930            Binder.restoreCallingIdentity(ident);
9931        }
9932    }
9933
9934    @Override
9935    public StackInfo getStackInfo(int stackId) {
9936        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9937        long ident = Binder.clearCallingIdentity();
9938        try {
9939            synchronized (this) {
9940                return mStackSupervisor.getStackInfoLocked(stackId);
9941            }
9942        } finally {
9943            Binder.restoreCallingIdentity(ident);
9944        }
9945    }
9946
9947    @Override
9948    public boolean isInHomeStack(int taskId) {
9949        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9950        long ident = Binder.clearCallingIdentity();
9951        try {
9952            synchronized (this) {
9953                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9954                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9955                return tr != null && tr.stack != null && tr.stack.isHomeStack();
9956            }
9957        } finally {
9958            Binder.restoreCallingIdentity(ident);
9959        }
9960    }
9961
9962    @Override
9963    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
9964        synchronized(this) {
9965            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
9966        }
9967    }
9968
9969    @Override
9970    public void updateDeviceOwner(String packageName) {
9971        final int callingUid = Binder.getCallingUid();
9972        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9973            throw new SecurityException("updateDeviceOwner called from non-system process");
9974        }
9975        synchronized (this) {
9976            mDeviceOwnerName = packageName;
9977        }
9978    }
9979
9980    @Override
9981    public void updateLockTaskPackages(int userId, String[] packages) {
9982        final int callingUid = Binder.getCallingUid();
9983        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9984            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
9985                    "updateLockTaskPackages()");
9986        }
9987        synchronized (this) {
9988            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
9989                    Arrays.toString(packages));
9990            mLockTaskPackages.put(userId, packages);
9991            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
9992        }
9993    }
9994
9995
9996    void startLockTaskModeLocked(TaskRecord task) {
9997        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
9998        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
9999            return;
10000        }
10001
10002        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10003        // is initiated by system after the pinning request was shown and locked mode is initiated
10004        // by an authorized app directly
10005        final int callingUid = Binder.getCallingUid();
10006        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10007        long ident = Binder.clearCallingIdentity();
10008        try {
10009            if (!isSystemInitiated) {
10010                task.mLockTaskUid = callingUid;
10011                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10012                    // startLockTask() called by app and task mode is lockTaskModeDefault.
10013                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10014                    StatusBarManagerInternal statusBarManager =
10015                            LocalServices.getService(StatusBarManagerInternal.class);
10016                    if (statusBarManager != null) {
10017                        statusBarManager.showScreenPinningRequest(task.taskId);
10018                    }
10019                    return;
10020                }
10021
10022                final ActivityStack stack = mStackSupervisor.getFocusedStack();
10023                if (stack == null || task != stack.topTask()) {
10024                    throw new IllegalArgumentException("Invalid task, not in foreground");
10025                }
10026            }
10027            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10028                    "Locking fully");
10029            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10030                    ActivityManager.LOCK_TASK_MODE_PINNED :
10031                    ActivityManager.LOCK_TASK_MODE_LOCKED,
10032                    "startLockTask", true);
10033        } finally {
10034            Binder.restoreCallingIdentity(ident);
10035        }
10036    }
10037
10038    @Override
10039    public void startLockTaskMode(int taskId) {
10040        synchronized (this) {
10041            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10042            if (task != null) {
10043                startLockTaskModeLocked(task);
10044            }
10045        }
10046    }
10047
10048    @Override
10049    public void startLockTaskMode(IBinder token) {
10050        synchronized (this) {
10051            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10052            if (r == null) {
10053                return;
10054            }
10055            final TaskRecord task = r.task;
10056            if (task != null) {
10057                startLockTaskModeLocked(task);
10058            }
10059        }
10060    }
10061
10062    @Override
10063    public void startSystemLockTaskMode(int taskId) throws RemoteException {
10064        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10065        // This makes inner call to look as if it was initiated by system.
10066        long ident = Binder.clearCallingIdentity();
10067        try {
10068            synchronized (this) {
10069                startLockTaskMode(taskId);
10070            }
10071        } finally {
10072            Binder.restoreCallingIdentity(ident);
10073        }
10074    }
10075
10076    @Override
10077    public void stopLockTaskMode() {
10078        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10079        if (lockTask == null) {
10080            // Our work here is done.
10081            return;
10082        }
10083
10084        final int callingUid = Binder.getCallingUid();
10085        final int lockTaskUid = lockTask.mLockTaskUid;
10086        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10087        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10088            // Done.
10089            return;
10090        } else {
10091            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10092            // It is possible lockTaskMode was started by the system process because
10093            // android:lockTaskMode is set to a locking value in the application manifest
10094            // instead of the app calling startLockTaskMode. In this case
10095            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10096            // {@link TaskRecord.effectiveUid} instead. Also caller with
10097            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10098            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10099                    && callingUid != lockTaskUid
10100                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10101                throw new SecurityException("Invalid uid, expected " + lockTaskUid
10102                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10103            }
10104        }
10105        long ident = Binder.clearCallingIdentity();
10106        try {
10107            Log.d(TAG, "stopLockTaskMode");
10108            // Stop lock task
10109            synchronized (this) {
10110                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10111                        "stopLockTask", true);
10112            }
10113        } finally {
10114            Binder.restoreCallingIdentity(ident);
10115        }
10116    }
10117
10118    /**
10119     * This API should be called by SystemUI only when user perform certain action to dismiss
10120     * lock task mode. We should only dismiss pinned lock task mode in this case.
10121     */
10122    @Override
10123    public void stopSystemLockTaskMode() throws RemoteException {
10124        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10125            stopLockTaskMode();
10126        } else {
10127            mStackSupervisor.showLockTaskToast();
10128        }
10129    }
10130
10131    @Override
10132    public boolean isInLockTaskMode() {
10133        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10134    }
10135
10136    @Override
10137    public int getLockTaskModeState() {
10138        synchronized (this) {
10139            return mStackSupervisor.getLockTaskModeState();
10140        }
10141    }
10142
10143    @Override
10144    public void showLockTaskEscapeMessage(IBinder token) {
10145        synchronized (this) {
10146            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10147            if (r == null) {
10148                return;
10149            }
10150            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10151        }
10152    }
10153
10154    // =========================================================
10155    // CONTENT PROVIDERS
10156    // =========================================================
10157
10158    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10159        List<ProviderInfo> providers = null;
10160        try {
10161            providers = AppGlobals.getPackageManager()
10162                    .queryContentProviders(app.processName, app.uid,
10163                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10164                                    | MATCH_DEBUG_TRIAGED_MISSING)
10165                    .getList();
10166        } catch (RemoteException ex) {
10167        }
10168        if (DEBUG_MU) Slog.v(TAG_MU,
10169                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10170        int userId = app.userId;
10171        if (providers != null) {
10172            int N = providers.size();
10173            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10174            for (int i=0; i<N; i++) {
10175                ProviderInfo cpi =
10176                    (ProviderInfo)providers.get(i);
10177                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10178                        cpi.name, cpi.flags);
10179                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10180                    // This is a singleton provider, but a user besides the
10181                    // default user is asking to initialize a process it runs
10182                    // in...  well, no, it doesn't actually run in this process,
10183                    // it runs in the process of the default user.  Get rid of it.
10184                    providers.remove(i);
10185                    N--;
10186                    i--;
10187                    continue;
10188                }
10189
10190                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10191                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10192                if (cpr == null) {
10193                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10194                    mProviderMap.putProviderByClass(comp, cpr);
10195                }
10196                if (DEBUG_MU) Slog.v(TAG_MU,
10197                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10198                app.pubProviders.put(cpi.name, cpr);
10199                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10200                    // Don't add this if it is a platform component that is marked
10201                    // to run in multiple processes, because this is actually
10202                    // part of the framework so doesn't make sense to track as a
10203                    // separate apk in the process.
10204                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10205                            mProcessStats);
10206                }
10207                notifyPackageUse(cpi.applicationInfo.packageName,
10208                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10209            }
10210        }
10211        return providers;
10212    }
10213
10214    /**
10215     * Check if {@link ProcessRecord} has a possible chance at accessing the
10216     * given {@link ProviderInfo}. Final permission checking is always done
10217     * in {@link ContentProvider}.
10218     */
10219    private final String checkContentProviderPermissionLocked(
10220            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10221        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10222        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10223        boolean checkedGrants = false;
10224        if (checkUser) {
10225            // Looking for cross-user grants before enforcing the typical cross-users permissions
10226            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10227            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10228                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10229                    return null;
10230                }
10231                checkedGrants = true;
10232            }
10233            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10234                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10235            if (userId != tmpTargetUserId) {
10236                // When we actually went to determine the final targer user ID, this ended
10237                // up different than our initial check for the authority.  This is because
10238                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10239                // SELF.  So we need to re-check the grants again.
10240                checkedGrants = false;
10241            }
10242        }
10243        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10244                cpi.applicationInfo.uid, cpi.exported)
10245                == PackageManager.PERMISSION_GRANTED) {
10246            return null;
10247        }
10248        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10249                cpi.applicationInfo.uid, cpi.exported)
10250                == PackageManager.PERMISSION_GRANTED) {
10251            return null;
10252        }
10253
10254        PathPermission[] pps = cpi.pathPermissions;
10255        if (pps != null) {
10256            int i = pps.length;
10257            while (i > 0) {
10258                i--;
10259                PathPermission pp = pps[i];
10260                String pprperm = pp.getReadPermission();
10261                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10262                        cpi.applicationInfo.uid, cpi.exported)
10263                        == PackageManager.PERMISSION_GRANTED) {
10264                    return null;
10265                }
10266                String ppwperm = pp.getWritePermission();
10267                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10268                        cpi.applicationInfo.uid, cpi.exported)
10269                        == PackageManager.PERMISSION_GRANTED) {
10270                    return null;
10271                }
10272            }
10273        }
10274        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10275            return null;
10276        }
10277
10278        String msg;
10279        if (!cpi.exported) {
10280            msg = "Permission Denial: opening provider " + cpi.name
10281                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10282                    + ", uid=" + callingUid + ") that is not exported from uid "
10283                    + cpi.applicationInfo.uid;
10284        } else {
10285            msg = "Permission Denial: opening provider " + cpi.name
10286                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10287                    + ", uid=" + callingUid + ") requires "
10288                    + cpi.readPermission + " or " + cpi.writePermission;
10289        }
10290        Slog.w(TAG, msg);
10291        return msg;
10292    }
10293
10294    /**
10295     * Returns if the ContentProvider has granted a uri to callingUid
10296     */
10297    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10298        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10299        if (perms != null) {
10300            for (int i=perms.size()-1; i>=0; i--) {
10301                GrantUri grantUri = perms.keyAt(i);
10302                if (grantUri.sourceUserId == userId || !checkUser) {
10303                    if (matchesProvider(grantUri.uri, cpi)) {
10304                        return true;
10305                    }
10306                }
10307            }
10308        }
10309        return false;
10310    }
10311
10312    /**
10313     * Returns true if the uri authority is one of the authorities specified in the provider.
10314     */
10315    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10316        String uriAuth = uri.getAuthority();
10317        String cpiAuth = cpi.authority;
10318        if (cpiAuth.indexOf(';') == -1) {
10319            return cpiAuth.equals(uriAuth);
10320        }
10321        String[] cpiAuths = cpiAuth.split(";");
10322        int length = cpiAuths.length;
10323        for (int i = 0; i < length; i++) {
10324            if (cpiAuths[i].equals(uriAuth)) return true;
10325        }
10326        return false;
10327    }
10328
10329    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10330            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10331        if (r != null) {
10332            for (int i=0; i<r.conProviders.size(); i++) {
10333                ContentProviderConnection conn = r.conProviders.get(i);
10334                if (conn.provider == cpr) {
10335                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10336                            "Adding provider requested by "
10337                            + r.processName + " from process "
10338                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10339                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10340                    if (stable) {
10341                        conn.stableCount++;
10342                        conn.numStableIncs++;
10343                    } else {
10344                        conn.unstableCount++;
10345                        conn.numUnstableIncs++;
10346                    }
10347                    return conn;
10348                }
10349            }
10350            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10351            if (stable) {
10352                conn.stableCount = 1;
10353                conn.numStableIncs = 1;
10354            } else {
10355                conn.unstableCount = 1;
10356                conn.numUnstableIncs = 1;
10357            }
10358            cpr.connections.add(conn);
10359            r.conProviders.add(conn);
10360            startAssociationLocked(r.uid, r.processName, r.curProcState,
10361                    cpr.uid, cpr.name, cpr.info.processName);
10362            return conn;
10363        }
10364        cpr.addExternalProcessHandleLocked(externalProcessToken);
10365        return null;
10366    }
10367
10368    boolean decProviderCountLocked(ContentProviderConnection conn,
10369            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10370        if (conn != null) {
10371            cpr = conn.provider;
10372            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10373                    "Removing provider requested by "
10374                    + conn.client.processName + " from process "
10375                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10376                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10377            if (stable) {
10378                conn.stableCount--;
10379            } else {
10380                conn.unstableCount--;
10381            }
10382            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10383                cpr.connections.remove(conn);
10384                conn.client.conProviders.remove(conn);
10385                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10386                    // The client is more important than last activity -- note the time this
10387                    // is happening, so we keep the old provider process around a bit as last
10388                    // activity to avoid thrashing it.
10389                    if (cpr.proc != null) {
10390                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10391                    }
10392                }
10393                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10394                return true;
10395            }
10396            return false;
10397        }
10398        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10399        return false;
10400    }
10401
10402    private void checkTime(long startTime, String where) {
10403        long now = SystemClock.uptimeMillis();
10404        if ((now-startTime) > 50) {
10405            // If we are taking more than 50ms, log about it.
10406            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10407        }
10408    }
10409
10410    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10411            String name, IBinder token, boolean stable, int userId) {
10412        ContentProviderRecord cpr;
10413        ContentProviderConnection conn = null;
10414        ProviderInfo cpi = null;
10415
10416        synchronized(this) {
10417            long startTime = SystemClock.uptimeMillis();
10418
10419            ProcessRecord r = null;
10420            if (caller != null) {
10421                r = getRecordForAppLocked(caller);
10422                if (r == null) {
10423                    throw new SecurityException(
10424                            "Unable to find app for caller " + caller
10425                          + " (pid=" + Binder.getCallingPid()
10426                          + ") when getting content provider " + name);
10427                }
10428            }
10429
10430            boolean checkCrossUser = true;
10431
10432            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10433
10434            // First check if this content provider has been published...
10435            cpr = mProviderMap.getProviderByName(name, userId);
10436            // If that didn't work, check if it exists for user 0 and then
10437            // verify that it's a singleton provider before using it.
10438            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10439                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10440                if (cpr != null) {
10441                    cpi = cpr.info;
10442                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10443                            cpi.name, cpi.flags)
10444                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10445                        userId = UserHandle.USER_SYSTEM;
10446                        checkCrossUser = false;
10447                    } else {
10448                        cpr = null;
10449                        cpi = null;
10450                    }
10451                }
10452            }
10453
10454            boolean providerRunning = cpr != null;
10455            if (providerRunning) {
10456                cpi = cpr.info;
10457                String msg;
10458                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10459                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10460                        != null) {
10461                    throw new SecurityException(msg);
10462                }
10463                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10464
10465                if (r != null && cpr.canRunHere(r)) {
10466                    // This provider has been published or is in the process
10467                    // of being published...  but it is also allowed to run
10468                    // in the caller's process, so don't make a connection
10469                    // and just let the caller instantiate its own instance.
10470                    ContentProviderHolder holder = cpr.newHolder(null);
10471                    // don't give caller the provider object, it needs
10472                    // to make its own.
10473                    holder.provider = null;
10474                    return holder;
10475                }
10476
10477                final long origId = Binder.clearCallingIdentity();
10478
10479                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10480
10481                // In this case the provider instance already exists, so we can
10482                // return it right away.
10483                conn = incProviderCountLocked(r, cpr, token, stable);
10484                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10485                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10486                        // If this is a perceptible app accessing the provider,
10487                        // make sure to count it as being accessed and thus
10488                        // back up on the LRU list.  This is good because
10489                        // content providers are often expensive to start.
10490                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10491                        updateLruProcessLocked(cpr.proc, false, null);
10492                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10493                    }
10494                }
10495
10496                if (cpr.proc != null) {
10497                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10498                    boolean success = updateOomAdjLocked(cpr.proc);
10499                    maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10500                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10501                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10502                    // NOTE: there is still a race here where a signal could be
10503                    // pending on the process even though we managed to update its
10504                    // adj level.  Not sure what to do about this, but at least
10505                    // the race is now smaller.
10506                    if (!success) {
10507                        // Uh oh...  it looks like the provider's process
10508                        // has been killed on us.  We need to wait for a new
10509                        // process to be started, and make sure its death
10510                        // doesn't kill our process.
10511                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10512                                + " is crashing; detaching " + r);
10513                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10514                        checkTime(startTime, "getContentProviderImpl: before appDied");
10515                        appDiedLocked(cpr.proc);
10516                        checkTime(startTime, "getContentProviderImpl: after appDied");
10517                        if (!lastRef) {
10518                            // This wasn't the last ref our process had on
10519                            // the provider...  we have now been killed, bail.
10520                            return null;
10521                        }
10522                        providerRunning = false;
10523                        conn = null;
10524                    }
10525                }
10526
10527                Binder.restoreCallingIdentity(origId);
10528            }
10529
10530            if (!providerRunning) {
10531                try {
10532                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10533                    cpi = AppGlobals.getPackageManager().
10534                        resolveContentProvider(name,
10535                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10536                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10537                } catch (RemoteException ex) {
10538                }
10539                if (cpi == null) {
10540                    return null;
10541                }
10542                // If the provider is a singleton AND
10543                // (it's a call within the same user || the provider is a
10544                // privileged app)
10545                // Then allow connecting to the singleton provider
10546                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10547                        cpi.name, cpi.flags)
10548                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10549                if (singleton) {
10550                    userId = UserHandle.USER_SYSTEM;
10551                }
10552                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10553                checkTime(startTime, "getContentProviderImpl: got app info for user");
10554
10555                String msg;
10556                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10557                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10558                        != null) {
10559                    throw new SecurityException(msg);
10560                }
10561                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10562
10563                if (!mProcessesReady
10564                        && !cpi.processName.equals("system")) {
10565                    // If this content provider does not run in the system
10566                    // process, and the system is not yet ready to run other
10567                    // processes, then fail fast instead of hanging.
10568                    throw new IllegalArgumentException(
10569                            "Attempt to launch content provider before system ready");
10570                }
10571
10572                // Make sure that the user who owns this provider is running.  If not,
10573                // we don't want to allow it to run.
10574                if (!mUserController.isUserRunningLocked(userId, 0)) {
10575                    Slog.w(TAG, "Unable to launch app "
10576                            + cpi.applicationInfo.packageName + "/"
10577                            + cpi.applicationInfo.uid + " for provider "
10578                            + name + ": user " + userId + " is stopped");
10579                    return null;
10580                }
10581
10582                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10583                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10584                cpr = mProviderMap.getProviderByClass(comp, userId);
10585                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10586                final boolean firstClass = cpr == null;
10587                if (firstClass) {
10588                    final long ident = Binder.clearCallingIdentity();
10589
10590                    // If permissions need a review before any of the app components can run,
10591                    // we return no provider and launch a review activity if the calling app
10592                    // is in the foreground.
10593                    if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10594                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10595                            return null;
10596                        }
10597                    }
10598
10599                    try {
10600                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10601                        ApplicationInfo ai =
10602                            AppGlobals.getPackageManager().
10603                                getApplicationInfo(
10604                                        cpi.applicationInfo.packageName,
10605                                        STOCK_PM_FLAGS, userId);
10606                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10607                        if (ai == null) {
10608                            Slog.w(TAG, "No package info for content provider "
10609                                    + cpi.name);
10610                            return null;
10611                        }
10612                        ai = getAppInfoForUser(ai, userId);
10613                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10614                    } catch (RemoteException ex) {
10615                        // pm is in same process, this will never happen.
10616                    } finally {
10617                        Binder.restoreCallingIdentity(ident);
10618                    }
10619                }
10620
10621                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10622
10623                if (r != null && cpr.canRunHere(r)) {
10624                    // If this is a multiprocess provider, then just return its
10625                    // info and allow the caller to instantiate it.  Only do
10626                    // this if the provider is the same user as the caller's
10627                    // process, or can run as root (so can be in any process).
10628                    return cpr.newHolder(null);
10629                }
10630
10631                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10632                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10633                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10634
10635                // This is single process, and our app is now connecting to it.
10636                // See if we are already in the process of launching this
10637                // provider.
10638                final int N = mLaunchingProviders.size();
10639                int i;
10640                for (i = 0; i < N; i++) {
10641                    if (mLaunchingProviders.get(i) == cpr) {
10642                        break;
10643                    }
10644                }
10645
10646                // If the provider is not already being launched, then get it
10647                // started.
10648                if (i >= N) {
10649                    final long origId = Binder.clearCallingIdentity();
10650
10651                    try {
10652                        // Content provider is now in use, its package can't be stopped.
10653                        try {
10654                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10655                            AppGlobals.getPackageManager().setPackageStoppedState(
10656                                    cpr.appInfo.packageName, false, userId);
10657                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10658                        } catch (RemoteException e) {
10659                        } catch (IllegalArgumentException e) {
10660                            Slog.w(TAG, "Failed trying to unstop package "
10661                                    + cpr.appInfo.packageName + ": " + e);
10662                        }
10663
10664                        // Use existing process if already started
10665                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10666                        ProcessRecord proc = getProcessRecordLocked(
10667                                cpi.processName, cpr.appInfo.uid, false);
10668                        if (proc != null && proc.thread != null) {
10669                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10670                                    "Installing in existing process " + proc);
10671                            if (!proc.pubProviders.containsKey(cpi.name)) {
10672                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10673                                proc.pubProviders.put(cpi.name, cpr);
10674                                try {
10675                                    proc.thread.scheduleInstallProvider(cpi);
10676                                } catch (RemoteException e) {
10677                                }
10678                            }
10679                        } else {
10680                            checkTime(startTime, "getContentProviderImpl: before start process");
10681                            proc = startProcessLocked(cpi.processName,
10682                                    cpr.appInfo, false, 0, "content provider",
10683                                    new ComponentName(cpi.applicationInfo.packageName,
10684                                            cpi.name), false, false, false);
10685                            checkTime(startTime, "getContentProviderImpl: after start process");
10686                            if (proc == null) {
10687                                Slog.w(TAG, "Unable to launch app "
10688                                        + cpi.applicationInfo.packageName + "/"
10689                                        + cpi.applicationInfo.uid + " for provider "
10690                                        + name + ": process is bad");
10691                                return null;
10692                            }
10693                        }
10694                        cpr.launchingApp = proc;
10695                        mLaunchingProviders.add(cpr);
10696                    } finally {
10697                        Binder.restoreCallingIdentity(origId);
10698                    }
10699                }
10700
10701                checkTime(startTime, "getContentProviderImpl: updating data structures");
10702
10703                // Make sure the provider is published (the same provider class
10704                // may be published under multiple names).
10705                if (firstClass) {
10706                    mProviderMap.putProviderByClass(comp, cpr);
10707                }
10708
10709                mProviderMap.putProviderByName(name, cpr);
10710                conn = incProviderCountLocked(r, cpr, token, stable);
10711                if (conn != null) {
10712                    conn.waiting = true;
10713                }
10714            }
10715            checkTime(startTime, "getContentProviderImpl: done!");
10716        }
10717
10718        // Wait for the provider to be published...
10719        synchronized (cpr) {
10720            while (cpr.provider == null) {
10721                if (cpr.launchingApp == null) {
10722                    Slog.w(TAG, "Unable to launch app "
10723                            + cpi.applicationInfo.packageName + "/"
10724                            + cpi.applicationInfo.uid + " for provider "
10725                            + name + ": launching app became null");
10726                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10727                            UserHandle.getUserId(cpi.applicationInfo.uid),
10728                            cpi.applicationInfo.packageName,
10729                            cpi.applicationInfo.uid, name);
10730                    return null;
10731                }
10732                try {
10733                    if (DEBUG_MU) Slog.v(TAG_MU,
10734                            "Waiting to start provider " + cpr
10735                            + " launchingApp=" + cpr.launchingApp);
10736                    if (conn != null) {
10737                        conn.waiting = true;
10738                    }
10739                    cpr.wait();
10740                } catch (InterruptedException ex) {
10741                } finally {
10742                    if (conn != null) {
10743                        conn.waiting = false;
10744                    }
10745                }
10746            }
10747        }
10748        return cpr != null ? cpr.newHolder(conn) : null;
10749    }
10750
10751    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10752            ProcessRecord r, final int userId) {
10753        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10754                cpi.packageName, userId)) {
10755
10756            final boolean callerForeground = r == null || r.setSchedGroup
10757                    != ProcessList.SCHED_GROUP_BACKGROUND;
10758
10759            // Show a permission review UI only for starting from a foreground app
10760            if (!callerForeground) {
10761                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
10762                        + cpi.packageName + " requires a permissions review");
10763                return false;
10764            }
10765
10766            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10767            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10768                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10769            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10770
10771            if (DEBUG_PERMISSIONS_REVIEW) {
10772                Slog.i(TAG, "u" + userId + " Launching permission review "
10773                        + "for package " + cpi.packageName);
10774            }
10775
10776            final UserHandle userHandle = new UserHandle(userId);
10777            mHandler.post(new Runnable() {
10778                @Override
10779                public void run() {
10780                    mContext.startActivityAsUser(intent, userHandle);
10781                }
10782            });
10783
10784            return false;
10785        }
10786
10787        return true;
10788    }
10789
10790    PackageManagerInternal getPackageManagerInternalLocked() {
10791        if (mPackageManagerInt == null) {
10792            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10793        }
10794        return mPackageManagerInt;
10795    }
10796
10797    @Override
10798    public final ContentProviderHolder getContentProvider(
10799            IApplicationThread caller, String name, int userId, boolean stable) {
10800        enforceNotIsolatedCaller("getContentProvider");
10801        if (caller == null) {
10802            String msg = "null IApplicationThread when getting content provider "
10803                    + name;
10804            Slog.w(TAG, msg);
10805            throw new SecurityException(msg);
10806        }
10807        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10808        // with cross-user grant.
10809        return getContentProviderImpl(caller, name, null, stable, userId);
10810    }
10811
10812    public ContentProviderHolder getContentProviderExternal(
10813            String name, int userId, IBinder token) {
10814        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10815            "Do not have permission in call getContentProviderExternal()");
10816        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10817                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10818        return getContentProviderExternalUnchecked(name, token, userId);
10819    }
10820
10821    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10822            IBinder token, int userId) {
10823        return getContentProviderImpl(null, name, token, true, userId);
10824    }
10825
10826    /**
10827     * Drop a content provider from a ProcessRecord's bookkeeping
10828     */
10829    public void removeContentProvider(IBinder connection, boolean stable) {
10830        enforceNotIsolatedCaller("removeContentProvider");
10831        long ident = Binder.clearCallingIdentity();
10832        try {
10833            synchronized (this) {
10834                ContentProviderConnection conn;
10835                try {
10836                    conn = (ContentProviderConnection)connection;
10837                } catch (ClassCastException e) {
10838                    String msg ="removeContentProvider: " + connection
10839                            + " not a ContentProviderConnection";
10840                    Slog.w(TAG, msg);
10841                    throw new IllegalArgumentException(msg);
10842                }
10843                if (conn == null) {
10844                    throw new NullPointerException("connection is null");
10845                }
10846                if (decProviderCountLocked(conn, null, null, stable)) {
10847                    updateOomAdjLocked();
10848                }
10849            }
10850        } finally {
10851            Binder.restoreCallingIdentity(ident);
10852        }
10853    }
10854
10855    public void removeContentProviderExternal(String name, IBinder token) {
10856        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10857            "Do not have permission in call removeContentProviderExternal()");
10858        int userId = UserHandle.getCallingUserId();
10859        long ident = Binder.clearCallingIdentity();
10860        try {
10861            removeContentProviderExternalUnchecked(name, token, userId);
10862        } finally {
10863            Binder.restoreCallingIdentity(ident);
10864        }
10865    }
10866
10867    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
10868        synchronized (this) {
10869            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
10870            if(cpr == null) {
10871                //remove from mProvidersByClass
10872                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
10873                return;
10874            }
10875
10876            //update content provider record entry info
10877            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
10878            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
10879            if (localCpr.hasExternalProcessHandles()) {
10880                if (localCpr.removeExternalProcessHandleLocked(token)) {
10881                    updateOomAdjLocked();
10882                } else {
10883                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
10884                            + " with no external reference for token: "
10885                            + token + ".");
10886                }
10887            } else {
10888                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
10889                        + " with no external references.");
10890            }
10891        }
10892    }
10893
10894    public final void publishContentProviders(IApplicationThread caller,
10895            List<ContentProviderHolder> providers) {
10896        if (providers == null) {
10897            return;
10898        }
10899
10900        enforceNotIsolatedCaller("publishContentProviders");
10901        synchronized (this) {
10902            final ProcessRecord r = getRecordForAppLocked(caller);
10903            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
10904            if (r == null) {
10905                throw new SecurityException(
10906                        "Unable to find app for caller " + caller
10907                      + " (pid=" + Binder.getCallingPid()
10908                      + ") when publishing content providers");
10909            }
10910
10911            final long origId = Binder.clearCallingIdentity();
10912
10913            final int N = providers.size();
10914            for (int i = 0; i < N; i++) {
10915                ContentProviderHolder src = providers.get(i);
10916                if (src == null || src.info == null || src.provider == null) {
10917                    continue;
10918                }
10919                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
10920                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
10921                if (dst != null) {
10922                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
10923                    mProviderMap.putProviderByClass(comp, dst);
10924                    String names[] = dst.info.authority.split(";");
10925                    for (int j = 0; j < names.length; j++) {
10926                        mProviderMap.putProviderByName(names[j], dst);
10927                    }
10928
10929                    int launchingCount = mLaunchingProviders.size();
10930                    int j;
10931                    boolean wasInLaunchingProviders = false;
10932                    for (j = 0; j < launchingCount; j++) {
10933                        if (mLaunchingProviders.get(j) == dst) {
10934                            mLaunchingProviders.remove(j);
10935                            wasInLaunchingProviders = true;
10936                            j--;
10937                            launchingCount--;
10938                        }
10939                    }
10940                    if (wasInLaunchingProviders) {
10941                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
10942                    }
10943                    synchronized (dst) {
10944                        dst.provider = src.provider;
10945                        dst.proc = r;
10946                        dst.notifyAll();
10947                    }
10948                    updateOomAdjLocked(r);
10949                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
10950                            src.info.authority);
10951                }
10952            }
10953
10954            Binder.restoreCallingIdentity(origId);
10955        }
10956    }
10957
10958    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
10959        ContentProviderConnection conn;
10960        try {
10961            conn = (ContentProviderConnection)connection;
10962        } catch (ClassCastException e) {
10963            String msg ="refContentProvider: " + connection
10964                    + " not a ContentProviderConnection";
10965            Slog.w(TAG, msg);
10966            throw new IllegalArgumentException(msg);
10967        }
10968        if (conn == null) {
10969            throw new NullPointerException("connection is null");
10970        }
10971
10972        synchronized (this) {
10973            if (stable > 0) {
10974                conn.numStableIncs += stable;
10975            }
10976            stable = conn.stableCount + stable;
10977            if (stable < 0) {
10978                throw new IllegalStateException("stableCount < 0: " + stable);
10979            }
10980
10981            if (unstable > 0) {
10982                conn.numUnstableIncs += unstable;
10983            }
10984            unstable = conn.unstableCount + unstable;
10985            if (unstable < 0) {
10986                throw new IllegalStateException("unstableCount < 0: " + unstable);
10987            }
10988
10989            if ((stable+unstable) <= 0) {
10990                throw new IllegalStateException("ref counts can't go to zero here: stable="
10991                        + stable + " unstable=" + unstable);
10992            }
10993            conn.stableCount = stable;
10994            conn.unstableCount = unstable;
10995            return !conn.dead;
10996        }
10997    }
10998
10999    public void unstableProviderDied(IBinder connection) {
11000        ContentProviderConnection conn;
11001        try {
11002            conn = (ContentProviderConnection)connection;
11003        } catch (ClassCastException e) {
11004            String msg ="refContentProvider: " + connection
11005                    + " not a ContentProviderConnection";
11006            Slog.w(TAG, msg);
11007            throw new IllegalArgumentException(msg);
11008        }
11009        if (conn == null) {
11010            throw new NullPointerException("connection is null");
11011        }
11012
11013        // Safely retrieve the content provider associated with the connection.
11014        IContentProvider provider;
11015        synchronized (this) {
11016            provider = conn.provider.provider;
11017        }
11018
11019        if (provider == null) {
11020            // Um, yeah, we're way ahead of you.
11021            return;
11022        }
11023
11024        // Make sure the caller is being honest with us.
11025        if (provider.asBinder().pingBinder()) {
11026            // Er, no, still looks good to us.
11027            synchronized (this) {
11028                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11029                        + " says " + conn + " died, but we don't agree");
11030                return;
11031            }
11032        }
11033
11034        // Well look at that!  It's dead!
11035        synchronized (this) {
11036            if (conn.provider.provider != provider) {
11037                // But something changed...  good enough.
11038                return;
11039            }
11040
11041            ProcessRecord proc = conn.provider.proc;
11042            if (proc == null || proc.thread == null) {
11043                // Seems like the process is already cleaned up.
11044                return;
11045            }
11046
11047            // As far as we're concerned, this is just like receiving a
11048            // death notification...  just a bit prematurely.
11049            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11050                    + ") early provider death");
11051            final long ident = Binder.clearCallingIdentity();
11052            try {
11053                appDiedLocked(proc);
11054            } finally {
11055                Binder.restoreCallingIdentity(ident);
11056            }
11057        }
11058    }
11059
11060    @Override
11061    public void appNotRespondingViaProvider(IBinder connection) {
11062        enforceCallingPermission(
11063                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11064
11065        final ContentProviderConnection conn = (ContentProviderConnection) connection;
11066        if (conn == null) {
11067            Slog.w(TAG, "ContentProviderConnection is null");
11068            return;
11069        }
11070
11071        final ProcessRecord host = conn.provider.proc;
11072        if (host == null) {
11073            Slog.w(TAG, "Failed to find hosting ProcessRecord");
11074            return;
11075        }
11076
11077        mHandler.post(new Runnable() {
11078            @Override
11079            public void run() {
11080                mAppErrors.appNotResponding(host, null, null, false,
11081                        "ContentProvider not responding");
11082            }
11083        });
11084    }
11085
11086    public final void installSystemProviders() {
11087        List<ProviderInfo> providers;
11088        synchronized (this) {
11089            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11090            providers = generateApplicationProvidersLocked(app);
11091            if (providers != null) {
11092                for (int i=providers.size()-1; i>=0; i--) {
11093                    ProviderInfo pi = (ProviderInfo)providers.get(i);
11094                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11095                        Slog.w(TAG, "Not installing system proc provider " + pi.name
11096                                + ": not system .apk");
11097                        providers.remove(i);
11098                    }
11099                }
11100            }
11101        }
11102        if (providers != null) {
11103            mSystemThread.installSystemProviders(providers);
11104        }
11105
11106        mCoreSettingsObserver = new CoreSettingsObserver(this);
11107        mFontScaleSettingObserver = new FontScaleSettingObserver();
11108
11109        //mUsageStatsService.monitorPackages();
11110    }
11111
11112    private void startPersistentApps(int matchFlags) {
11113        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11114
11115        synchronized (this) {
11116            try {
11117                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11118                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11119                for (ApplicationInfo app : apps) {
11120                    if (!"android".equals(app.packageName)) {
11121                        addAppLocked(app, false, null /* ABI override */);
11122                    }
11123                }
11124            } catch (RemoteException ex) {
11125            }
11126        }
11127    }
11128
11129    /**
11130     * When a user is unlocked, we need to install encryption-unaware providers
11131     * belonging to any running apps.
11132     */
11133    private void installEncryptionUnawareProviders(int userId) {
11134        // We're only interested in providers that are encryption unaware, and
11135        // we don't care about uninstalled apps, since there's no way they're
11136        // running at this point.
11137        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11138
11139        synchronized (this) {
11140            final int NP = mProcessNames.getMap().size();
11141            for (int ip = 0; ip < NP; ip++) {
11142                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11143                final int NA = apps.size();
11144                for (int ia = 0; ia < NA; ia++) {
11145                    final ProcessRecord app = apps.valueAt(ia);
11146                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11147
11148                    final int NG = app.pkgList.size();
11149                    for (int ig = 0; ig < NG; ig++) {
11150                        try {
11151                            final String pkgName = app.pkgList.keyAt(ig);
11152                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11153                                    .getPackageInfo(pkgName, matchFlags, userId);
11154                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11155                                for (ProviderInfo provInfo : pkgInfo.providers) {
11156                                    if (Objects.equals(provInfo.processName, app.processName)) {
11157                                        Log.v(TAG, "Installing " + provInfo);
11158                                        app.thread.scheduleInstallProvider(provInfo);
11159                                    } else {
11160                                        Log.v(TAG, "Skipping " + provInfo);
11161                                    }
11162                                }
11163                            }
11164                        } catch (RemoteException ignored) {
11165                        }
11166                    }
11167                }
11168            }
11169        }
11170    }
11171
11172    /**
11173     * Allows apps to retrieve the MIME type of a URI.
11174     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11175     * users, then it does not need permission to access the ContentProvider.
11176     * Either, it needs cross-user uri grants.
11177     *
11178     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11179     *
11180     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11181     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11182     */
11183    public String getProviderMimeType(Uri uri, int userId) {
11184        enforceNotIsolatedCaller("getProviderMimeType");
11185        final String name = uri.getAuthority();
11186        int callingUid = Binder.getCallingUid();
11187        int callingPid = Binder.getCallingPid();
11188        long ident = 0;
11189        boolean clearedIdentity = false;
11190        synchronized (this) {
11191            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11192        }
11193        if (canClearIdentity(callingPid, callingUid, userId)) {
11194            clearedIdentity = true;
11195            ident = Binder.clearCallingIdentity();
11196        }
11197        ContentProviderHolder holder = null;
11198        try {
11199            holder = getContentProviderExternalUnchecked(name, null, userId);
11200            if (holder != null) {
11201                return holder.provider.getType(uri);
11202            }
11203        } catch (RemoteException e) {
11204            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11205            return null;
11206        } finally {
11207            // We need to clear the identity to call removeContentProviderExternalUnchecked
11208            if (!clearedIdentity) {
11209                ident = Binder.clearCallingIdentity();
11210            }
11211            try {
11212                if (holder != null) {
11213                    removeContentProviderExternalUnchecked(name, null, userId);
11214                }
11215            } finally {
11216                Binder.restoreCallingIdentity(ident);
11217            }
11218        }
11219
11220        return null;
11221    }
11222
11223    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11224        if (UserHandle.getUserId(callingUid) == userId) {
11225            return true;
11226        }
11227        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11228                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11229                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11230                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11231                return true;
11232        }
11233        return false;
11234    }
11235
11236    // =========================================================
11237    // GLOBAL MANAGEMENT
11238    // =========================================================
11239
11240    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11241            boolean isolated, int isolatedUid) {
11242        String proc = customProcess != null ? customProcess : info.processName;
11243        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11244        final int userId = UserHandle.getUserId(info.uid);
11245        int uid = info.uid;
11246        if (isolated) {
11247            if (isolatedUid == 0) {
11248                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11249                while (true) {
11250                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11251                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11252                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11253                    }
11254                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11255                    mNextIsolatedProcessUid++;
11256                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11257                        // No process for this uid, use it.
11258                        break;
11259                    }
11260                    stepsLeft--;
11261                    if (stepsLeft <= 0) {
11262                        return null;
11263                    }
11264                }
11265            } else {
11266                // Special case for startIsolatedProcess (internal only), where
11267                // the uid of the isolated process is specified by the caller.
11268                uid = isolatedUid;
11269            }
11270        }
11271        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11272        if (!mBooted && !mBooting
11273                && userId == UserHandle.USER_SYSTEM
11274                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11275            r.persistent = true;
11276        }
11277        addProcessNameLocked(r);
11278        return r;
11279    }
11280
11281    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11282            String abiOverride) {
11283        ProcessRecord app;
11284        if (!isolated) {
11285            app = getProcessRecordLocked(info.processName, info.uid, true);
11286        } else {
11287            app = null;
11288        }
11289
11290        if (app == null) {
11291            app = newProcessRecordLocked(info, null, isolated, 0);
11292            updateLruProcessLocked(app, false, null);
11293            updateOomAdjLocked();
11294        }
11295
11296        // This package really, really can not be stopped.
11297        try {
11298            AppGlobals.getPackageManager().setPackageStoppedState(
11299                    info.packageName, false, UserHandle.getUserId(app.uid));
11300        } catch (RemoteException e) {
11301        } catch (IllegalArgumentException e) {
11302            Slog.w(TAG, "Failed trying to unstop package "
11303                    + info.packageName + ": " + e);
11304        }
11305
11306        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11307            app.persistent = true;
11308            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11309        }
11310        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11311            mPersistentStartingProcesses.add(app);
11312            startProcessLocked(app, "added application", app.processName, abiOverride,
11313                    null /* entryPoint */, null /* entryPointArgs */);
11314        }
11315
11316        return app;
11317    }
11318
11319    public void unhandledBack() {
11320        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11321                "unhandledBack()");
11322
11323        synchronized(this) {
11324            final long origId = Binder.clearCallingIdentity();
11325            try {
11326                getFocusedStack().unhandledBackLocked();
11327            } finally {
11328                Binder.restoreCallingIdentity(origId);
11329            }
11330        }
11331    }
11332
11333    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11334        enforceNotIsolatedCaller("openContentUri");
11335        final int userId = UserHandle.getCallingUserId();
11336        String name = uri.getAuthority();
11337        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11338        ParcelFileDescriptor pfd = null;
11339        if (cph != null) {
11340            // We record the binder invoker's uid in thread-local storage before
11341            // going to the content provider to open the file.  Later, in the code
11342            // that handles all permissions checks, we look for this uid and use
11343            // that rather than the Activity Manager's own uid.  The effect is that
11344            // we do the check against the caller's permissions even though it looks
11345            // to the content provider like the Activity Manager itself is making
11346            // the request.
11347            Binder token = new Binder();
11348            sCallerIdentity.set(new Identity(
11349                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11350            try {
11351                pfd = cph.provider.openFile(null, uri, "r", null, token);
11352            } catch (FileNotFoundException e) {
11353                // do nothing; pfd will be returned null
11354            } finally {
11355                // Ensure that whatever happens, we clean up the identity state
11356                sCallerIdentity.remove();
11357                // Ensure we're done with the provider.
11358                removeContentProviderExternalUnchecked(name, null, userId);
11359            }
11360        } else {
11361            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11362        }
11363        return pfd;
11364    }
11365
11366    // Actually is sleeping or shutting down or whatever else in the future
11367    // is an inactive state.
11368    public boolean isSleepingOrShuttingDown() {
11369        return isSleeping() || mShuttingDown;
11370    }
11371
11372    public boolean isSleeping() {
11373        return mSleeping;
11374    }
11375
11376    void onWakefulnessChanged(int wakefulness) {
11377        synchronized(this) {
11378            mWakefulness = wakefulness;
11379            updateSleepIfNeededLocked();
11380        }
11381    }
11382
11383    void finishRunningVoiceLocked() {
11384        if (mRunningVoice != null) {
11385            mRunningVoice = null;
11386            mVoiceWakeLock.release();
11387            updateSleepIfNeededLocked();
11388        }
11389    }
11390
11391    void startTimeTrackingFocusedActivityLocked() {
11392        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11393            mCurAppTimeTracker.start(mFocusedActivity.packageName);
11394        }
11395    }
11396
11397    void updateSleepIfNeededLocked() {
11398        if (mSleeping && !shouldSleepLocked()) {
11399            mSleeping = false;
11400            startTimeTrackingFocusedActivityLocked();
11401            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11402            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11403            updateOomAdjLocked();
11404        } else if (!mSleeping && shouldSleepLocked()) {
11405            mSleeping = true;
11406            if (mCurAppTimeTracker != null) {
11407                mCurAppTimeTracker.stop();
11408            }
11409            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11410            mStackSupervisor.goingToSleepLocked();
11411            updateOomAdjLocked();
11412
11413            // Initialize the wake times of all processes.
11414            checkExcessivePowerUsageLocked(false);
11415            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11416            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11417            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11418        }
11419    }
11420
11421    private boolean shouldSleepLocked() {
11422        // Resume applications while running a voice interactor.
11423        if (mRunningVoice != null) {
11424            return false;
11425        }
11426
11427        // TODO: Transform the lock screen state into a sleep token instead.
11428        switch (mWakefulness) {
11429            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11430            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11431            case PowerManagerInternal.WAKEFULNESS_DOZING:
11432                // Pause applications whenever the lock screen is shown or any sleep
11433                // tokens have been acquired.
11434                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11435            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11436            default:
11437                // If we're asleep then pause applications unconditionally.
11438                return true;
11439        }
11440    }
11441
11442    /** Pokes the task persister. */
11443    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11444        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11445    }
11446
11447    /** Notifies all listeners when the task stack has changed. */
11448    void notifyTaskStackChangedLocked() {
11449        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11450        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11451        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11452        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11453    }
11454
11455    /** Notifies all listeners when an Activity is pinned. */
11456    void notifyActivityPinnedLocked() {
11457        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11458        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11459    }
11460
11461    /**
11462     * Notifies all listeners when an attempt was made to start an an activity that is already
11463     * running in the pinned stack and the activity was not actually started, but the task is
11464     * either brought to the front or a new Intent is delivered to it.
11465     */
11466    void notifyPinnedActivityRestartAttemptLocked() {
11467        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11468        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11469    }
11470
11471    /** Notifies all listeners when the pinned stack animation ends. */
11472    @Override
11473    public void notifyPinnedStackAnimationEnded() {
11474        synchronized (this) {
11475            mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11476            mHandler.obtainMessage(
11477                    NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11478        }
11479    }
11480
11481    @Override
11482    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11483        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11484    }
11485
11486    @Override
11487    public boolean shutdown(int timeout) {
11488        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11489                != PackageManager.PERMISSION_GRANTED) {
11490            throw new SecurityException("Requires permission "
11491                    + android.Manifest.permission.SHUTDOWN);
11492        }
11493
11494        boolean timedout = false;
11495
11496        synchronized(this) {
11497            mShuttingDown = true;
11498            updateEventDispatchingLocked();
11499            timedout = mStackSupervisor.shutdownLocked(timeout);
11500        }
11501
11502        mAppOpsService.shutdown();
11503        if (mUsageStatsService != null) {
11504            mUsageStatsService.prepareShutdown();
11505        }
11506        mBatteryStatsService.shutdown();
11507        synchronized (this) {
11508            mProcessStats.shutdownLocked();
11509            notifyTaskPersisterLocked(null, true);
11510        }
11511
11512        return timedout;
11513    }
11514
11515    public final void activitySlept(IBinder token) {
11516        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11517
11518        final long origId = Binder.clearCallingIdentity();
11519
11520        synchronized (this) {
11521            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11522            if (r != null) {
11523                mStackSupervisor.activitySleptLocked(r);
11524            }
11525        }
11526
11527        Binder.restoreCallingIdentity(origId);
11528    }
11529
11530    private String lockScreenShownToString() {
11531        switch (mLockScreenShown) {
11532            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11533            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11534            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11535            default: return "Unknown=" + mLockScreenShown;
11536        }
11537    }
11538
11539    void logLockScreen(String msg) {
11540        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11541                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11542                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11543                + " mSleeping=" + mSleeping);
11544    }
11545
11546    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11547        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11548        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11549        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11550            boolean wasRunningVoice = mRunningVoice != null;
11551            mRunningVoice = session;
11552            if (!wasRunningVoice) {
11553                mVoiceWakeLock.acquire();
11554                updateSleepIfNeededLocked();
11555            }
11556        }
11557    }
11558
11559    private void updateEventDispatchingLocked() {
11560        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11561    }
11562
11563    public void setLockScreenShown(boolean showing, boolean occluded) {
11564        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11565                != PackageManager.PERMISSION_GRANTED) {
11566            throw new SecurityException("Requires permission "
11567                    + android.Manifest.permission.DEVICE_POWER);
11568        }
11569
11570        synchronized(this) {
11571            long ident = Binder.clearCallingIdentity();
11572            try {
11573                if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
11574                mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11575                if (showing && occluded) {
11576                    // The lock screen is currently showing, but is occluded by a window that can
11577                    // show on top of the lock screen. In this can we want to dismiss the docked
11578                    // stack since it will be complicated/risky to try to put the activity on top
11579                    // of the lock screen in the right fullscreen configuration.
11580                    mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
11581                            mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
11582                }
11583
11584                updateSleepIfNeededLocked();
11585            } finally {
11586                Binder.restoreCallingIdentity(ident);
11587            }
11588        }
11589    }
11590
11591    @Override
11592    public void notifyLockedProfile(@UserIdInt int userId) {
11593        try {
11594            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11595                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11596            }
11597        } catch (RemoteException ex) {
11598            throw new SecurityException("Fail to check is caller a privileged app", ex);
11599        }
11600
11601        synchronized (this) {
11602            if (mStackSupervisor.isUserLockedProfile(userId)) {
11603                final long ident = Binder.clearCallingIdentity();
11604                try {
11605                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11606                    if (mUserController.isLockScreenDisabled(currentUserId)) {
11607                        // If there is no device lock, we will show the profile's credential page.
11608                        mActivityStarter.showConfirmDeviceCredential(userId);
11609                    } else {
11610                        // Showing launcher to avoid user entering credential twice.
11611                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11612                    }
11613                } finally {
11614                    Binder.restoreCallingIdentity(ident);
11615                }
11616            }
11617        }
11618    }
11619
11620    @Override
11621    public void startConfirmDeviceCredentialIntent(Intent intent) {
11622        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11623        synchronized (this) {
11624            final long ident = Binder.clearCallingIdentity();
11625            try {
11626                mActivityStarter.startConfirmCredentialIntent(intent);
11627            } finally {
11628                Binder.restoreCallingIdentity(ident);
11629            }
11630        }
11631    }
11632
11633    @Override
11634    public void stopAppSwitches() {
11635        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11636                != PackageManager.PERMISSION_GRANTED) {
11637            throw new SecurityException("viewquires permission "
11638                    + android.Manifest.permission.STOP_APP_SWITCHES);
11639        }
11640
11641        synchronized(this) {
11642            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11643                    + APP_SWITCH_DELAY_TIME;
11644            mDidAppSwitch = false;
11645            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11646            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11647            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11648        }
11649    }
11650
11651    public void resumeAppSwitches() {
11652        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11653                != PackageManager.PERMISSION_GRANTED) {
11654            throw new SecurityException("Requires permission "
11655                    + android.Manifest.permission.STOP_APP_SWITCHES);
11656        }
11657
11658        synchronized(this) {
11659            // Note that we don't execute any pending app switches... we will
11660            // let those wait until either the timeout, or the next start
11661            // activity request.
11662            mAppSwitchesAllowedTime = 0;
11663        }
11664    }
11665
11666    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11667            int callingPid, int callingUid, String name) {
11668        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11669            return true;
11670        }
11671
11672        int perm = checkComponentPermission(
11673                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11674                sourceUid, -1, true);
11675        if (perm == PackageManager.PERMISSION_GRANTED) {
11676            return true;
11677        }
11678
11679        // If the actual IPC caller is different from the logical source, then
11680        // also see if they are allowed to control app switches.
11681        if (callingUid != -1 && callingUid != sourceUid) {
11682            perm = checkComponentPermission(
11683                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11684                    callingUid, -1, true);
11685            if (perm == PackageManager.PERMISSION_GRANTED) {
11686                return true;
11687            }
11688        }
11689
11690        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11691        return false;
11692    }
11693
11694    public void setDebugApp(String packageName, boolean waitForDebugger,
11695            boolean persistent) {
11696        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11697                "setDebugApp()");
11698
11699        long ident = Binder.clearCallingIdentity();
11700        try {
11701            // Note that this is not really thread safe if there are multiple
11702            // callers into it at the same time, but that's not a situation we
11703            // care about.
11704            if (persistent) {
11705                final ContentResolver resolver = mContext.getContentResolver();
11706                Settings.Global.putString(
11707                    resolver, Settings.Global.DEBUG_APP,
11708                    packageName);
11709                Settings.Global.putInt(
11710                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11711                    waitForDebugger ? 1 : 0);
11712            }
11713
11714            synchronized (this) {
11715                if (!persistent) {
11716                    mOrigDebugApp = mDebugApp;
11717                    mOrigWaitForDebugger = mWaitForDebugger;
11718                }
11719                mDebugApp = packageName;
11720                mWaitForDebugger = waitForDebugger;
11721                mDebugTransient = !persistent;
11722                if (packageName != null) {
11723                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11724                            false, UserHandle.USER_ALL, "set debug app");
11725                }
11726            }
11727        } finally {
11728            Binder.restoreCallingIdentity(ident);
11729        }
11730    }
11731
11732    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11733        synchronized (this) {
11734            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11735            if (!isDebuggable) {
11736                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11737                    throw new SecurityException("Process not debuggable: " + app.packageName);
11738                }
11739            }
11740
11741            mTrackAllocationApp = processName;
11742        }
11743    }
11744
11745    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11746        synchronized (this) {
11747            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11748            if (!isDebuggable) {
11749                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11750                    throw new SecurityException("Process not debuggable: " + app.packageName);
11751                }
11752            }
11753            mProfileApp = processName;
11754            mProfileFile = profilerInfo.profileFile;
11755            if (mProfileFd != null) {
11756                try {
11757                    mProfileFd.close();
11758                } catch (IOException e) {
11759                }
11760                mProfileFd = null;
11761            }
11762            mProfileFd = profilerInfo.profileFd;
11763            mSamplingInterval = profilerInfo.samplingInterval;
11764            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11765            mProfileType = 0;
11766        }
11767    }
11768
11769    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11770        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11771        if (!isDebuggable) {
11772            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11773                throw new SecurityException("Process not debuggable: " + app.packageName);
11774            }
11775        }
11776        mNativeDebuggingApp = processName;
11777    }
11778
11779    @Override
11780    public void setAlwaysFinish(boolean enabled) {
11781        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11782                "setAlwaysFinish()");
11783
11784        long ident = Binder.clearCallingIdentity();
11785        try {
11786            Settings.Global.putInt(
11787                    mContext.getContentResolver(),
11788                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11789
11790            synchronized (this) {
11791                mAlwaysFinishActivities = enabled;
11792            }
11793        } finally {
11794            Binder.restoreCallingIdentity(ident);
11795        }
11796    }
11797
11798    @Override
11799    public void setLenientBackgroundCheck(boolean enabled) {
11800        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
11801                "setLenientBackgroundCheck()");
11802
11803        long ident = Binder.clearCallingIdentity();
11804        try {
11805            Settings.Global.putInt(
11806                    mContext.getContentResolver(),
11807                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
11808
11809            synchronized (this) {
11810                mLenientBackgroundCheck = enabled;
11811            }
11812        } finally {
11813            Binder.restoreCallingIdentity(ident);
11814        }
11815    }
11816
11817    @Override
11818    public void setActivityController(IActivityController controller, boolean imAMonkey) {
11819        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11820                "setActivityController()");
11821        synchronized (this) {
11822            mController = controller;
11823            mControllerIsAMonkey = imAMonkey;
11824            Watchdog.getInstance().setActivityController(controller);
11825        }
11826    }
11827
11828    @Override
11829    public void setUserIsMonkey(boolean userIsMonkey) {
11830        synchronized (this) {
11831            synchronized (mPidsSelfLocked) {
11832                final int callingPid = Binder.getCallingPid();
11833                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
11834                if (precessRecord == null) {
11835                    throw new SecurityException("Unknown process: " + callingPid);
11836                }
11837                if (precessRecord.instrumentationUiAutomationConnection  == null) {
11838                    throw new SecurityException("Only an instrumentation process "
11839                            + "with a UiAutomation can call setUserIsMonkey");
11840                }
11841            }
11842            mUserIsMonkey = userIsMonkey;
11843        }
11844    }
11845
11846    @Override
11847    public boolean isUserAMonkey() {
11848        synchronized (this) {
11849            // If there is a controller also implies the user is a monkey.
11850            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
11851        }
11852    }
11853
11854    public void requestBugReport(int bugreportType) {
11855        String service = null;
11856        switch (bugreportType) {
11857            case ActivityManager.BUGREPORT_OPTION_FULL:
11858                service = "bugreport";
11859                break;
11860            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
11861                service = "bugreportplus";
11862                break;
11863            case ActivityManager.BUGREPORT_OPTION_REMOTE:
11864                service = "bugreportremote";
11865                break;
11866        }
11867        if (service == null) {
11868            throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
11869                    + bugreportType);
11870        }
11871        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
11872        SystemProperties.set("ctl.start", service);
11873    }
11874
11875    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
11876        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
11877    }
11878
11879    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
11880        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
11881            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
11882        }
11883        return KEY_DISPATCHING_TIMEOUT;
11884    }
11885
11886    @Override
11887    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
11888        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11889                != PackageManager.PERMISSION_GRANTED) {
11890            throw new SecurityException("Requires permission "
11891                    + android.Manifest.permission.FILTER_EVENTS);
11892        }
11893        ProcessRecord proc;
11894        long timeout;
11895        synchronized (this) {
11896            synchronized (mPidsSelfLocked) {
11897                proc = mPidsSelfLocked.get(pid);
11898            }
11899            timeout = getInputDispatchingTimeoutLocked(proc);
11900        }
11901
11902        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
11903            return -1;
11904        }
11905
11906        return timeout;
11907    }
11908
11909    /**
11910     * Handle input dispatching timeouts.
11911     * Returns whether input dispatching should be aborted or not.
11912     */
11913    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
11914            final ActivityRecord activity, final ActivityRecord parent,
11915            final boolean aboveSystem, String reason) {
11916        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11917                != PackageManager.PERMISSION_GRANTED) {
11918            throw new SecurityException("Requires permission "
11919                    + android.Manifest.permission.FILTER_EVENTS);
11920        }
11921
11922        final String annotation;
11923        if (reason == null) {
11924            annotation = "Input dispatching timed out";
11925        } else {
11926            annotation = "Input dispatching timed out (" + reason + ")";
11927        }
11928
11929        if (proc != null) {
11930            synchronized (this) {
11931                if (proc.debugging) {
11932                    return false;
11933                }
11934
11935                if (mDidDexOpt) {
11936                    // Give more time since we were dexopting.
11937                    mDidDexOpt = false;
11938                    return false;
11939                }
11940
11941                if (proc.instrumentationClass != null) {
11942                    Bundle info = new Bundle();
11943                    info.putString("shortMsg", "keyDispatchingTimedOut");
11944                    info.putString("longMsg", annotation);
11945                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
11946                    return true;
11947                }
11948            }
11949            mHandler.post(new Runnable() {
11950                @Override
11951                public void run() {
11952                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
11953                }
11954            });
11955        }
11956
11957        return true;
11958    }
11959
11960    @Override
11961    public Bundle getAssistContextExtras(int requestType) {
11962        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
11963                null, null, true /* focused */, true /* newSessionId */,
11964                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
11965        if (pae == null) {
11966            return null;
11967        }
11968        synchronized (pae) {
11969            while (!pae.haveResult) {
11970                try {
11971                    pae.wait();
11972                } catch (InterruptedException e) {
11973                }
11974            }
11975        }
11976        synchronized (this) {
11977            buildAssistBundleLocked(pae, pae.result);
11978            mPendingAssistExtras.remove(pae);
11979            mUiHandler.removeCallbacks(pae);
11980        }
11981        return pae.extras;
11982    }
11983
11984    @Override
11985    public boolean isAssistDataAllowedOnCurrentActivity() {
11986        int userId;
11987        synchronized (this) {
11988            userId = mUserController.getCurrentUserIdLocked();
11989            ActivityRecord activity = getFocusedStack().topActivity();
11990            if (activity == null) {
11991                return false;
11992            }
11993            userId = activity.userId;
11994        }
11995        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
11996                Context.DEVICE_POLICY_SERVICE);
11997        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
11998    }
11999
12000    @Override
12001    public boolean showAssistFromActivity(IBinder token, Bundle args) {
12002        long ident = Binder.clearCallingIdentity();
12003        try {
12004            synchronized (this) {
12005                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12006                ActivityRecord top = getFocusedStack().topActivity();
12007                if (top != caller) {
12008                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12009                            + " is not current top " + top);
12010                    return false;
12011                }
12012                if (!top.nowVisible) {
12013                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12014                            + " is not visible");
12015                    return false;
12016                }
12017            }
12018            AssistUtils utils = new AssistUtils(mContext);
12019            return utils.showSessionForActiveService(args,
12020                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
12021        } finally {
12022            Binder.restoreCallingIdentity(ident);
12023        }
12024    }
12025
12026    @Override
12027    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12028            Bundle receiverExtras,
12029            IBinder activityToken, boolean focused, boolean newSessionId) {
12030        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12031                activityToken, focused, newSessionId,
12032                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
12033                != null;
12034    }
12035
12036    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12037            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12038            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12039        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12040                "enqueueAssistContext()");
12041        synchronized (this) {
12042            ActivityRecord activity = getFocusedStack().topActivity();
12043            if (activity == null) {
12044                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12045                return null;
12046            }
12047            if (activity.app == null || activity.app.thread == null) {
12048                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12049                return null;
12050            }
12051            if (focused) {
12052                if (activityToken != null) {
12053                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12054                    if (activity != caller) {
12055                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12056                                + " is not current top " + activity);
12057                        return null;
12058                    }
12059                }
12060            } else {
12061                activity = ActivityRecord.forTokenLocked(activityToken);
12062                if (activity == null) {
12063                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12064                            + " couldn't be found");
12065                    return null;
12066                }
12067            }
12068
12069            PendingAssistExtras pae;
12070            Bundle extras = new Bundle();
12071            if (args != null) {
12072                extras.putAll(args);
12073            }
12074            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12075            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12076            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12077                    userHandle);
12078            // Increment the sessionId if necessary
12079            if (newSessionId) {
12080                mViSessionId++;
12081            }
12082            try {
12083                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12084                        requestType, mViSessionId);
12085                mPendingAssistExtras.add(pae);
12086                mUiHandler.postDelayed(pae, timeout);
12087            } catch (RemoteException e) {
12088                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12089                return null;
12090            }
12091            return pae;
12092        }
12093    }
12094
12095    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12096        IResultReceiver receiver;
12097        synchronized (this) {
12098            mPendingAssistExtras.remove(pae);
12099            receiver = pae.receiver;
12100        }
12101        if (receiver != null) {
12102            // Caller wants result sent back to them.
12103            Bundle sendBundle = new Bundle();
12104            // At least return the receiver extras
12105            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12106                    pae.receiverExtras);
12107            try {
12108                pae.receiver.send(0, sendBundle);
12109            } catch (RemoteException e) {
12110            }
12111        }
12112    }
12113
12114    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12115        if (result != null) {
12116            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12117        }
12118        if (pae.hint != null) {
12119            pae.extras.putBoolean(pae.hint, true);
12120        }
12121    }
12122
12123    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12124            AssistContent content, Uri referrer) {
12125        PendingAssistExtras pae = (PendingAssistExtras)token;
12126        synchronized (pae) {
12127            pae.result = extras;
12128            pae.structure = structure;
12129            pae.content = content;
12130            if (referrer != null) {
12131                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12132            }
12133            pae.haveResult = true;
12134            pae.notifyAll();
12135            if (pae.intent == null && pae.receiver == null) {
12136                // Caller is just waiting for the result.
12137                return;
12138            }
12139        }
12140
12141        // We are now ready to launch the assist activity.
12142        IResultReceiver sendReceiver = null;
12143        Bundle sendBundle = null;
12144        synchronized (this) {
12145            buildAssistBundleLocked(pae, extras);
12146            boolean exists = mPendingAssistExtras.remove(pae);
12147            mUiHandler.removeCallbacks(pae);
12148            if (!exists) {
12149                // Timed out.
12150                return;
12151            }
12152            if ((sendReceiver=pae.receiver) != null) {
12153                // Caller wants result sent back to them.
12154                sendBundle = new Bundle();
12155                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12156                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12157                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12158                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12159                        pae.receiverExtras);
12160            }
12161        }
12162        if (sendReceiver != null) {
12163            try {
12164                sendReceiver.send(0, sendBundle);
12165            } catch (RemoteException e) {
12166            }
12167            return;
12168        }
12169
12170        long ident = Binder.clearCallingIdentity();
12171        try {
12172            pae.intent.replaceExtras(pae.extras);
12173            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12174                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12175                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12176            closeSystemDialogs("assist");
12177            try {
12178                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12179            } catch (ActivityNotFoundException e) {
12180                Slog.w(TAG, "No activity to handle assist action.", e);
12181            }
12182        } finally {
12183            Binder.restoreCallingIdentity(ident);
12184        }
12185    }
12186
12187    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12188            Bundle args) {
12189        return enqueueAssistContext(requestType, intent, hint, null, null, null,
12190                true /* focused */, true /* newSessionId */,
12191                userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12192    }
12193
12194    public void registerProcessObserver(IProcessObserver observer) {
12195        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12196                "registerProcessObserver()");
12197        synchronized (this) {
12198            mProcessObservers.register(observer);
12199        }
12200    }
12201
12202    @Override
12203    public void unregisterProcessObserver(IProcessObserver observer) {
12204        synchronized (this) {
12205            mProcessObservers.unregister(observer);
12206        }
12207    }
12208
12209    @Override
12210    public void registerUidObserver(IUidObserver observer, int which) {
12211        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12212                "registerUidObserver()");
12213        synchronized (this) {
12214            mUidObservers.register(observer, which);
12215        }
12216    }
12217
12218    @Override
12219    public void unregisterUidObserver(IUidObserver observer) {
12220        synchronized (this) {
12221            mUidObservers.unregister(observer);
12222        }
12223    }
12224
12225    @Override
12226    public boolean convertFromTranslucent(IBinder token) {
12227        final long origId = Binder.clearCallingIdentity();
12228        try {
12229            synchronized (this) {
12230                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12231                if (r == null) {
12232                    return false;
12233                }
12234                final boolean translucentChanged = r.changeWindowTranslucency(true);
12235                if (translucentChanged) {
12236                    r.task.stack.releaseBackgroundResources(r);
12237                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12238                }
12239                mWindowManager.setAppFullscreen(token, true);
12240                return translucentChanged;
12241            }
12242        } finally {
12243            Binder.restoreCallingIdentity(origId);
12244        }
12245    }
12246
12247    @Override
12248    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12249        final long origId = Binder.clearCallingIdentity();
12250        try {
12251            synchronized (this) {
12252                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12253                if (r == null) {
12254                    return false;
12255                }
12256                int index = r.task.mActivities.lastIndexOf(r);
12257                if (index > 0) {
12258                    ActivityRecord under = r.task.mActivities.get(index - 1);
12259                    under.returningOptions = options;
12260                }
12261                final boolean translucentChanged = r.changeWindowTranslucency(false);
12262                if (translucentChanged) {
12263                    r.task.stack.convertActivityToTranslucent(r);
12264                }
12265                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12266                mWindowManager.setAppFullscreen(token, false);
12267                return translucentChanged;
12268            }
12269        } finally {
12270            Binder.restoreCallingIdentity(origId);
12271        }
12272    }
12273
12274    @Override
12275    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12276        final long origId = Binder.clearCallingIdentity();
12277        try {
12278            synchronized (this) {
12279                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12280                if (r != null) {
12281                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12282                }
12283            }
12284            return false;
12285        } finally {
12286            Binder.restoreCallingIdentity(origId);
12287        }
12288    }
12289
12290    @Override
12291    public boolean isBackgroundVisibleBehind(IBinder token) {
12292        final long origId = Binder.clearCallingIdentity();
12293        try {
12294            synchronized (this) {
12295                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12296                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12297                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12298                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12299                return visible;
12300            }
12301        } finally {
12302            Binder.restoreCallingIdentity(origId);
12303        }
12304    }
12305
12306    @Override
12307    public ActivityOptions getActivityOptions(IBinder token) {
12308        final long origId = Binder.clearCallingIdentity();
12309        try {
12310            synchronized (this) {
12311                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12312                if (r != null) {
12313                    final ActivityOptions activityOptions = r.pendingOptions;
12314                    r.pendingOptions = null;
12315                    return activityOptions;
12316                }
12317                return null;
12318            }
12319        } finally {
12320            Binder.restoreCallingIdentity(origId);
12321        }
12322    }
12323
12324    @Override
12325    public void setImmersive(IBinder token, boolean immersive) {
12326        synchronized(this) {
12327            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12328            if (r == null) {
12329                throw new IllegalArgumentException();
12330            }
12331            r.immersive = immersive;
12332
12333            // update associated state if we're frontmost
12334            if (r == mFocusedActivity) {
12335                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12336                applyUpdateLockStateLocked(r);
12337            }
12338        }
12339    }
12340
12341    @Override
12342    public boolean isImmersive(IBinder token) {
12343        synchronized (this) {
12344            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12345            if (r == null) {
12346                throw new IllegalArgumentException();
12347            }
12348            return r.immersive;
12349        }
12350    }
12351
12352    @Override
12353    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12354        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12355            throw new UnsupportedOperationException("VR mode not supported on this device!");
12356        }
12357
12358        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12359
12360        ActivityRecord r;
12361        synchronized (this) {
12362            r = ActivityRecord.isInStackLocked(token);
12363        }
12364
12365        if (r == null) {
12366            throw new IllegalArgumentException();
12367        }
12368
12369        int err;
12370        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12371                VrManagerInternal.NO_ERROR) {
12372            return err;
12373        }
12374
12375        synchronized(this) {
12376            r.requestedVrComponent = (enabled) ? packageName : null;
12377
12378            // Update associated state if this activity is currently focused
12379            if (r == mFocusedActivity) {
12380                applyUpdateVrModeLocked(r);
12381            }
12382            return 0;
12383        }
12384    }
12385
12386    @Override
12387    public boolean isVrModePackageEnabled(ComponentName packageName) {
12388        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12389            throw new UnsupportedOperationException("VR mode not supported on this device!");
12390        }
12391
12392        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12393
12394        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12395                VrManagerInternal.NO_ERROR;
12396    }
12397
12398    public boolean isTopActivityImmersive() {
12399        enforceNotIsolatedCaller("startActivity");
12400        synchronized (this) {
12401            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12402            return (r != null) ? r.immersive : false;
12403        }
12404    }
12405
12406    @Override
12407    public boolean isTopOfTask(IBinder token) {
12408        synchronized (this) {
12409            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12410            if (r == null) {
12411                throw new IllegalArgumentException();
12412            }
12413            return r.task.getTopActivity() == r;
12414        }
12415    }
12416
12417    public final void enterSafeMode() {
12418        synchronized(this) {
12419            // It only makes sense to do this before the system is ready
12420            // and started launching other packages.
12421            if (!mSystemReady) {
12422                try {
12423                    AppGlobals.getPackageManager().enterSafeMode();
12424                } catch (RemoteException e) {
12425                }
12426            }
12427
12428            mSafeMode = true;
12429        }
12430    }
12431
12432    public final void showSafeModeOverlay() {
12433        View v = LayoutInflater.from(mContext).inflate(
12434                com.android.internal.R.layout.safe_mode, null);
12435        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12436        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12437        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12438        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12439        lp.gravity = Gravity.BOTTOM | Gravity.START;
12440        lp.format = v.getBackground().getOpacity();
12441        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12442                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12443        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12444        ((WindowManager)mContext.getSystemService(
12445                Context.WINDOW_SERVICE)).addView(v, lp);
12446    }
12447
12448    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12449        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12450            return;
12451        }
12452        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12453        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12454        synchronized (stats) {
12455            if (mBatteryStatsService.isOnBattery()) {
12456                mBatteryStatsService.enforceCallingPermission();
12457                int MY_UID = Binder.getCallingUid();
12458                final int uid;
12459                if (sender == null) {
12460                    uid = sourceUid;
12461                } else {
12462                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12463                }
12464                BatteryStatsImpl.Uid.Pkg pkg =
12465                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12466                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12467                pkg.noteWakeupAlarmLocked(tag);
12468            }
12469        }
12470    }
12471
12472    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12473        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12474            return;
12475        }
12476        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12477        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12478        synchronized (stats) {
12479            mBatteryStatsService.enforceCallingPermission();
12480            int MY_UID = Binder.getCallingUid();
12481            final int uid;
12482            if (sender == null) {
12483                uid = sourceUid;
12484            } else {
12485                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12486            }
12487            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12488        }
12489    }
12490
12491    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12492        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12493            return;
12494        }
12495        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12496        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12497        synchronized (stats) {
12498            mBatteryStatsService.enforceCallingPermission();
12499            int MY_UID = Binder.getCallingUid();
12500            final int uid;
12501            if (sender == null) {
12502                uid = sourceUid;
12503            } else {
12504                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12505            }
12506            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12507        }
12508    }
12509
12510    public boolean killPids(int[] pids, String pReason, boolean secure) {
12511        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12512            throw new SecurityException("killPids only available to the system");
12513        }
12514        String reason = (pReason == null) ? "Unknown" : pReason;
12515        // XXX Note: don't acquire main activity lock here, because the window
12516        // manager calls in with its locks held.
12517
12518        boolean killed = false;
12519        synchronized (mPidsSelfLocked) {
12520            int worstType = 0;
12521            for (int i=0; i<pids.length; i++) {
12522                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12523                if (proc != null) {
12524                    int type = proc.setAdj;
12525                    if (type > worstType) {
12526                        worstType = type;
12527                    }
12528                }
12529            }
12530
12531            // If the worst oom_adj is somewhere in the cached proc LRU range,
12532            // then constrain it so we will kill all cached procs.
12533            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12534                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12535                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12536            }
12537
12538            // If this is not a secure call, don't let it kill processes that
12539            // are important.
12540            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12541                worstType = ProcessList.SERVICE_ADJ;
12542            }
12543
12544            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12545            for (int i=0; i<pids.length; i++) {
12546                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12547                if (proc == null) {
12548                    continue;
12549                }
12550                int adj = proc.setAdj;
12551                if (adj >= worstType && !proc.killedByAm) {
12552                    proc.kill(reason, true);
12553                    killed = true;
12554                }
12555            }
12556        }
12557        return killed;
12558    }
12559
12560    @Override
12561    public void killUid(int appId, int userId, String reason) {
12562        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12563        synchronized (this) {
12564            final long identity = Binder.clearCallingIdentity();
12565            try {
12566                killPackageProcessesLocked(null, appId, userId,
12567                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12568                        reason != null ? reason : "kill uid");
12569            } finally {
12570                Binder.restoreCallingIdentity(identity);
12571            }
12572        }
12573    }
12574
12575    @Override
12576    public boolean killProcessesBelowForeground(String reason) {
12577        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12578            throw new SecurityException("killProcessesBelowForeground() only available to system");
12579        }
12580
12581        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12582    }
12583
12584    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12585        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12586            throw new SecurityException("killProcessesBelowAdj() only available to system");
12587        }
12588
12589        boolean killed = false;
12590        synchronized (mPidsSelfLocked) {
12591            final int size = mPidsSelfLocked.size();
12592            for (int i = 0; i < size; i++) {
12593                final int pid = mPidsSelfLocked.keyAt(i);
12594                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12595                if (proc == null) continue;
12596
12597                final int adj = proc.setAdj;
12598                if (adj > belowAdj && !proc.killedByAm) {
12599                    proc.kill(reason, true);
12600                    killed = true;
12601                }
12602            }
12603        }
12604        return killed;
12605    }
12606
12607    @Override
12608    public void hang(final IBinder who, boolean allowRestart) {
12609        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12610                != PackageManager.PERMISSION_GRANTED) {
12611            throw new SecurityException("Requires permission "
12612                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12613        }
12614
12615        final IBinder.DeathRecipient death = new DeathRecipient() {
12616            @Override
12617            public void binderDied() {
12618                synchronized (this) {
12619                    notifyAll();
12620                }
12621            }
12622        };
12623
12624        try {
12625            who.linkToDeath(death, 0);
12626        } catch (RemoteException e) {
12627            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12628            return;
12629        }
12630
12631        synchronized (this) {
12632            Watchdog.getInstance().setAllowRestart(allowRestart);
12633            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12634            synchronized (death) {
12635                while (who.isBinderAlive()) {
12636                    try {
12637                        death.wait();
12638                    } catch (InterruptedException e) {
12639                    }
12640                }
12641            }
12642            Watchdog.getInstance().setAllowRestart(true);
12643        }
12644    }
12645
12646    @Override
12647    public void restart() {
12648        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12649                != PackageManager.PERMISSION_GRANTED) {
12650            throw new SecurityException("Requires permission "
12651                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12652        }
12653
12654        Log.i(TAG, "Sending shutdown broadcast...");
12655
12656        BroadcastReceiver br = new BroadcastReceiver() {
12657            @Override public void onReceive(Context context, Intent intent) {
12658                // Now the broadcast is done, finish up the low-level shutdown.
12659                Log.i(TAG, "Shutting down activity manager...");
12660                shutdown(10000);
12661                Log.i(TAG, "Shutdown complete, restarting!");
12662                Process.killProcess(Process.myPid());
12663                System.exit(10);
12664            }
12665        };
12666
12667        // First send the high-level shut down broadcast.
12668        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12669        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12670        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12671        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12672        mContext.sendOrderedBroadcastAsUser(intent,
12673                UserHandle.ALL, null, br, mHandler, 0, null, null);
12674        */
12675        br.onReceive(mContext, intent);
12676    }
12677
12678    private long getLowRamTimeSinceIdle(long now) {
12679        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12680    }
12681
12682    @Override
12683    public void performIdleMaintenance() {
12684        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12685                != PackageManager.PERMISSION_GRANTED) {
12686            throw new SecurityException("Requires permission "
12687                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12688        }
12689
12690        synchronized (this) {
12691            final long now = SystemClock.uptimeMillis();
12692            final long timeSinceLastIdle = now - mLastIdleTime;
12693            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12694            mLastIdleTime = now;
12695            mLowRamTimeSinceLastIdle = 0;
12696            if (mLowRamStartTime != 0) {
12697                mLowRamStartTime = now;
12698            }
12699
12700            StringBuilder sb = new StringBuilder(128);
12701            sb.append("Idle maintenance over ");
12702            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12703            sb.append(" low RAM for ");
12704            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12705            Slog.i(TAG, sb.toString());
12706
12707            // If at least 1/3 of our time since the last idle period has been spent
12708            // with RAM low, then we want to kill processes.
12709            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12710
12711            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12712                ProcessRecord proc = mLruProcesses.get(i);
12713                if (proc.notCachedSinceIdle) {
12714                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12715                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12716                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12717                        if (doKilling && proc.initialIdlePss != 0
12718                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12719                            sb = new StringBuilder(128);
12720                            sb.append("Kill");
12721                            sb.append(proc.processName);
12722                            sb.append(" in idle maint: pss=");
12723                            sb.append(proc.lastPss);
12724                            sb.append(", swapPss=");
12725                            sb.append(proc.lastSwapPss);
12726                            sb.append(", initialPss=");
12727                            sb.append(proc.initialIdlePss);
12728                            sb.append(", period=");
12729                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12730                            sb.append(", lowRamPeriod=");
12731                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12732                            Slog.wtfQuiet(TAG, sb.toString());
12733                            proc.kill("idle maint (pss " + proc.lastPss
12734                                    + " from " + proc.initialIdlePss + ")", true);
12735                        }
12736                    }
12737                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
12738                        && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
12739                    proc.notCachedSinceIdle = true;
12740                    proc.initialIdlePss = 0;
12741                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
12742                            mTestPssMode, isSleeping(), now);
12743                }
12744            }
12745
12746            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12747            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12748        }
12749    }
12750
12751    @Override
12752    public void sendIdleJobTrigger() {
12753        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12754                != PackageManager.PERMISSION_GRANTED) {
12755            throw new SecurityException("Requires permission "
12756                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12757        }
12758
12759        final long ident = Binder.clearCallingIdentity();
12760        try {
12761            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
12762                    .setPackage("android")
12763                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12764            broadcastIntent(null, intent, null, null, 0, null, null, null,
12765                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
12766        } finally {
12767            Binder.restoreCallingIdentity(ident);
12768        }
12769    }
12770
12771    private void retrieveSettings() {
12772        final ContentResolver resolver = mContext.getContentResolver();
12773        final boolean freeformWindowManagement =
12774                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
12775                        || Settings.Global.getInt(
12776                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
12777        final boolean supportsPictureInPicture =
12778                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
12779
12780        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
12781        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
12782        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
12783        final boolean alwaysFinishActivities =
12784                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
12785        final boolean lenientBackgroundCheck =
12786                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
12787        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
12788        final boolean forceResizable = Settings.Global.getInt(
12789                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
12790        final boolean supportsLeanbackOnly =
12791                mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
12792
12793        // Transfer any global setting for forcing RTL layout, into a System Property
12794        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
12795
12796        final Configuration configuration = new Configuration();
12797        Settings.System.getConfiguration(resolver, configuration);
12798        if (forceRtl) {
12799            // This will take care of setting the correct layout direction flags
12800            configuration.setLayoutDirection(configuration.locale);
12801        }
12802
12803        synchronized (this) {
12804            mDebugApp = mOrigDebugApp = debugApp;
12805            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
12806            mAlwaysFinishActivities = alwaysFinishActivities;
12807            mLenientBackgroundCheck = lenientBackgroundCheck;
12808            mSupportsLeanbackOnly = supportsLeanbackOnly;
12809            mForceResizableActivities = forceResizable;
12810            mWindowManager.setForceResizableTasks(mForceResizableActivities);
12811            if (supportsMultiWindow || forceResizable) {
12812                mSupportsMultiWindow = true;
12813                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
12814                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
12815            } else {
12816                mSupportsMultiWindow = false;
12817                mSupportsFreeformWindowManagement = false;
12818                mSupportsPictureInPicture = false;
12819            }
12820            // This happens before any activities are started, so we can
12821            // change mConfiguration in-place.
12822            updateConfigurationLocked(configuration, null, true);
12823            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
12824                    "Initial config: " + mConfiguration);
12825
12826            // Load resources only after the current configuration has been set.
12827            final Resources res = mContext.getResources();
12828            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
12829            mThumbnailWidth = res.getDimensionPixelSize(
12830                    com.android.internal.R.dimen.thumbnail_width);
12831            mThumbnailHeight = res.getDimensionPixelSize(
12832                    com.android.internal.R.dimen.thumbnail_height);
12833            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
12834                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
12835            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
12836                    com.android.internal.R.string.config_appsNotReportingCrashes));
12837            if ((mConfiguration.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
12838                mFullscreenThumbnailScale = (float) res
12839                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
12840                    (float) mConfiguration.screenWidthDp;
12841            } else {
12842                mFullscreenThumbnailScale = res.getFraction(
12843                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
12844            }
12845        }
12846    }
12847
12848    public boolean testIsSystemReady() {
12849        // no need to synchronize(this) just to read & return the value
12850        return mSystemReady;
12851    }
12852
12853    public void systemReady(final Runnable goingCallback) {
12854        synchronized(this) {
12855            if (mSystemReady) {
12856                // If we're done calling all the receivers, run the next "boot phase" passed in
12857                // by the SystemServer
12858                if (goingCallback != null) {
12859                    goingCallback.run();
12860                }
12861                return;
12862            }
12863
12864            mLocalDeviceIdleController
12865                    = LocalServices.getService(DeviceIdleController.LocalService.class);
12866
12867            // Make sure we have the current profile info, since it is needed for security checks.
12868            mUserController.onSystemReady();
12869            mRecentTasks.onSystemReadyLocked();
12870            mAppOpsService.systemReady();
12871            mSystemReady = true;
12872        }
12873
12874        ArrayList<ProcessRecord> procsToKill = null;
12875        synchronized(mPidsSelfLocked) {
12876            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
12877                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12878                if (!isAllowedWhileBooting(proc.info)){
12879                    if (procsToKill == null) {
12880                        procsToKill = new ArrayList<ProcessRecord>();
12881                    }
12882                    procsToKill.add(proc);
12883                }
12884            }
12885        }
12886
12887        synchronized(this) {
12888            if (procsToKill != null) {
12889                for (int i=procsToKill.size()-1; i>=0; i--) {
12890                    ProcessRecord proc = procsToKill.get(i);
12891                    Slog.i(TAG, "Removing system update proc: " + proc);
12892                    removeProcessLocked(proc, true, false, "system update done");
12893                }
12894            }
12895
12896            // Now that we have cleaned up any update processes, we
12897            // are ready to start launching real processes and know that
12898            // we won't trample on them any more.
12899            mProcessesReady = true;
12900        }
12901
12902        Slog.i(TAG, "System now ready");
12903        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
12904            SystemClock.uptimeMillis());
12905
12906        synchronized(this) {
12907            // Make sure we have no pre-ready processes sitting around.
12908
12909            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12910                ResolveInfo ri = mContext.getPackageManager()
12911                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
12912                                STOCK_PM_FLAGS);
12913                CharSequence errorMsg = null;
12914                if (ri != null) {
12915                    ActivityInfo ai = ri.activityInfo;
12916                    ApplicationInfo app = ai.applicationInfo;
12917                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12918                        mTopAction = Intent.ACTION_FACTORY_TEST;
12919                        mTopData = null;
12920                        mTopComponent = new ComponentName(app.packageName,
12921                                ai.name);
12922                    } else {
12923                        errorMsg = mContext.getResources().getText(
12924                                com.android.internal.R.string.factorytest_not_system);
12925                    }
12926                } else {
12927                    errorMsg = mContext.getResources().getText(
12928                            com.android.internal.R.string.factorytest_no_action);
12929                }
12930                if (errorMsg != null) {
12931                    mTopAction = null;
12932                    mTopData = null;
12933                    mTopComponent = null;
12934                    Message msg = Message.obtain();
12935                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
12936                    msg.getData().putCharSequence("msg", errorMsg);
12937                    mUiHandler.sendMessage(msg);
12938                }
12939            }
12940        }
12941
12942        retrieveSettings();
12943        final int currentUserId;
12944        synchronized (this) {
12945            currentUserId = mUserController.getCurrentUserIdLocked();
12946            readGrantedUriPermissionsLocked();
12947        }
12948
12949        if (goingCallback != null) goingCallback.run();
12950
12951        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
12952                Integer.toString(currentUserId), currentUserId);
12953        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
12954                Integer.toString(currentUserId), currentUserId);
12955        mSystemServiceManager.startUser(currentUserId);
12956
12957        synchronized (this) {
12958            // Only start up encryption-aware persistent apps; once user is
12959            // unlocked we'll come back around and start unaware apps
12960            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
12961
12962            // Start up initial activity.
12963            mBooting = true;
12964            // Enable home activity for system user, so that the system can always boot
12965            if (UserManager.isSplitSystemUser()) {
12966                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
12967                try {
12968                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
12969                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
12970                            UserHandle.USER_SYSTEM);
12971                } catch (RemoteException e) {
12972                    throw e.rethrowAsRuntimeException();
12973                }
12974            }
12975            startHomeActivityLocked(currentUserId, "systemReady");
12976
12977            try {
12978                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
12979                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
12980                            + " data partition or your device will be unstable.");
12981                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
12982                }
12983            } catch (RemoteException e) {
12984            }
12985
12986            if (!Build.isBuildConsistent()) {
12987                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
12988                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
12989            }
12990
12991            long ident = Binder.clearCallingIdentity();
12992            try {
12993                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
12994                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12995                        | Intent.FLAG_RECEIVER_FOREGROUND);
12996                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12997                broadcastIntentLocked(null, null, intent,
12998                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
12999                        null, false, false, MY_PID, Process.SYSTEM_UID,
13000                        currentUserId);
13001                intent = new Intent(Intent.ACTION_USER_STARTING);
13002                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13003                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13004                broadcastIntentLocked(null, null, intent,
13005                        null, new IIntentReceiver.Stub() {
13006                            @Override
13007                            public void performReceive(Intent intent, int resultCode, String data,
13008                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13009                                    throws RemoteException {
13010                            }
13011                        }, 0, null, null,
13012                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13013                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13014            } catch (Throwable t) {
13015                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13016            } finally {
13017                Binder.restoreCallingIdentity(ident);
13018            }
13019            mStackSupervisor.resumeFocusedStackTopActivityLocked();
13020            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13021        }
13022    }
13023
13024    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13025        synchronized (this) {
13026            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13027        }
13028    }
13029
13030    void skipCurrentReceiverLocked(ProcessRecord app) {
13031        for (BroadcastQueue queue : mBroadcastQueues) {
13032            queue.skipCurrentReceiverLocked(app);
13033        }
13034    }
13035
13036    /**
13037     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13038     * The application process will exit immediately after this call returns.
13039     * @param app object of the crashing app, null for the system server
13040     * @param crashInfo describing the exception
13041     */
13042    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
13043        ProcessRecord r = findAppProcess(app, "Crash");
13044        final String processName = app == null ? "system_server"
13045                : (r == null ? "unknown" : r.processName);
13046
13047        handleApplicationCrashInner("crash", r, processName, crashInfo);
13048    }
13049
13050    /* Native crash reporting uses this inner version because it needs to be somewhat
13051     * decoupled from the AM-managed cleanup lifecycle
13052     */
13053    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13054            ApplicationErrorReport.CrashInfo crashInfo) {
13055        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13056                UserHandle.getUserId(Binder.getCallingUid()), processName,
13057                r == null ? -1 : r.info.flags,
13058                crashInfo.exceptionClassName,
13059                crashInfo.exceptionMessage,
13060                crashInfo.throwFileName,
13061                crashInfo.throwLineNumber);
13062
13063        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13064
13065        mAppErrors.crashApplication(r, crashInfo);
13066    }
13067
13068    public void handleApplicationStrictModeViolation(
13069            IBinder app,
13070            int violationMask,
13071            StrictMode.ViolationInfo info) {
13072        ProcessRecord r = findAppProcess(app, "StrictMode");
13073        if (r == null) {
13074            return;
13075        }
13076
13077        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13078            Integer stackFingerprint = info.hashCode();
13079            boolean logIt = true;
13080            synchronized (mAlreadyLoggedViolatedStacks) {
13081                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13082                    logIt = false;
13083                    // TODO: sub-sample into EventLog for these, with
13084                    // the info.durationMillis?  Then we'd get
13085                    // the relative pain numbers, without logging all
13086                    // the stack traces repeatedly.  We'd want to do
13087                    // likewise in the client code, which also does
13088                    // dup suppression, before the Binder call.
13089                } else {
13090                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13091                        mAlreadyLoggedViolatedStacks.clear();
13092                    }
13093                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13094                }
13095            }
13096            if (logIt) {
13097                logStrictModeViolationToDropBox(r, info);
13098            }
13099        }
13100
13101        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13102            AppErrorResult result = new AppErrorResult();
13103            synchronized (this) {
13104                final long origId = Binder.clearCallingIdentity();
13105
13106                Message msg = Message.obtain();
13107                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13108                HashMap<String, Object> data = new HashMap<String, Object>();
13109                data.put("result", result);
13110                data.put("app", r);
13111                data.put("violationMask", violationMask);
13112                data.put("info", info);
13113                msg.obj = data;
13114                mUiHandler.sendMessage(msg);
13115
13116                Binder.restoreCallingIdentity(origId);
13117            }
13118            int res = result.get();
13119            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13120        }
13121    }
13122
13123    // Depending on the policy in effect, there could be a bunch of
13124    // these in quick succession so we try to batch these together to
13125    // minimize disk writes, number of dropbox entries, and maximize
13126    // compression, by having more fewer, larger records.
13127    private void logStrictModeViolationToDropBox(
13128            ProcessRecord process,
13129            StrictMode.ViolationInfo info) {
13130        if (info == null) {
13131            return;
13132        }
13133        final boolean isSystemApp = process == null ||
13134                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13135                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13136        final String processName = process == null ? "unknown" : process.processName;
13137        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13138        final DropBoxManager dbox = (DropBoxManager)
13139                mContext.getSystemService(Context.DROPBOX_SERVICE);
13140
13141        // Exit early if the dropbox isn't configured to accept this report type.
13142        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13143
13144        boolean bufferWasEmpty;
13145        boolean needsFlush;
13146        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13147        synchronized (sb) {
13148            bufferWasEmpty = sb.length() == 0;
13149            appendDropBoxProcessHeaders(process, processName, sb);
13150            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13151            sb.append("System-App: ").append(isSystemApp).append("\n");
13152            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13153            if (info.violationNumThisLoop != 0) {
13154                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13155            }
13156            if (info.numAnimationsRunning != 0) {
13157                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13158            }
13159            if (info.broadcastIntentAction != null) {
13160                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13161            }
13162            if (info.durationMillis != -1) {
13163                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13164            }
13165            if (info.numInstances != -1) {
13166                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13167            }
13168            if (info.tags != null) {
13169                for (String tag : info.tags) {
13170                    sb.append("Span-Tag: ").append(tag).append("\n");
13171                }
13172            }
13173            sb.append("\n");
13174            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13175                sb.append(info.crashInfo.stackTrace);
13176                sb.append("\n");
13177            }
13178            if (info.message != null) {
13179                sb.append(info.message);
13180                sb.append("\n");
13181            }
13182
13183            // Only buffer up to ~64k.  Various logging bits truncate
13184            // things at 128k.
13185            needsFlush = (sb.length() > 64 * 1024);
13186        }
13187
13188        // Flush immediately if the buffer's grown too large, or this
13189        // is a non-system app.  Non-system apps are isolated with a
13190        // different tag & policy and not batched.
13191        //
13192        // Batching is useful during internal testing with
13193        // StrictMode settings turned up high.  Without batching,
13194        // thousands of separate files could be created on boot.
13195        if (!isSystemApp || needsFlush) {
13196            new Thread("Error dump: " + dropboxTag) {
13197                @Override
13198                public void run() {
13199                    String report;
13200                    synchronized (sb) {
13201                        report = sb.toString();
13202                        sb.delete(0, sb.length());
13203                        sb.trimToSize();
13204                    }
13205                    if (report.length() != 0) {
13206                        dbox.addText(dropboxTag, report);
13207                    }
13208                }
13209            }.start();
13210            return;
13211        }
13212
13213        // System app batching:
13214        if (!bufferWasEmpty) {
13215            // An existing dropbox-writing thread is outstanding, so
13216            // we don't need to start it up.  The existing thread will
13217            // catch the buffer appends we just did.
13218            return;
13219        }
13220
13221        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13222        // (After this point, we shouldn't access AMS internal data structures.)
13223        new Thread("Error dump: " + dropboxTag) {
13224            @Override
13225            public void run() {
13226                // 5 second sleep to let stacks arrive and be batched together
13227                try {
13228                    Thread.sleep(5000);  // 5 seconds
13229                } catch (InterruptedException e) {}
13230
13231                String errorReport;
13232                synchronized (mStrictModeBuffer) {
13233                    errorReport = mStrictModeBuffer.toString();
13234                    if (errorReport.length() == 0) {
13235                        return;
13236                    }
13237                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13238                    mStrictModeBuffer.trimToSize();
13239                }
13240                dbox.addText(dropboxTag, errorReport);
13241            }
13242        }.start();
13243    }
13244
13245    /**
13246     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13247     * @param app object of the crashing app, null for the system server
13248     * @param tag reported by the caller
13249     * @param system whether this wtf is coming from the system
13250     * @param crashInfo describing the context of the error
13251     * @return true if the process should exit immediately (WTF is fatal)
13252     */
13253    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13254            final ApplicationErrorReport.CrashInfo crashInfo) {
13255        final int callingUid = Binder.getCallingUid();
13256        final int callingPid = Binder.getCallingPid();
13257
13258        if (system) {
13259            // If this is coming from the system, we could very well have low-level
13260            // system locks held, so we want to do this all asynchronously.  And we
13261            // never want this to become fatal, so there is that too.
13262            mHandler.post(new Runnable() {
13263                @Override public void run() {
13264                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13265                }
13266            });
13267            return false;
13268        }
13269
13270        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13271                crashInfo);
13272
13273        if (r != null && r.pid != Process.myPid() &&
13274                Settings.Global.getInt(mContext.getContentResolver(),
13275                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13276            mAppErrors.crashApplication(r, crashInfo);
13277            return true;
13278        } else {
13279            return false;
13280        }
13281    }
13282
13283    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13284            final ApplicationErrorReport.CrashInfo crashInfo) {
13285        final ProcessRecord r = findAppProcess(app, "WTF");
13286        final String processName = app == null ? "system_server"
13287                : (r == null ? "unknown" : r.processName);
13288
13289        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13290                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13291
13292        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13293
13294        return r;
13295    }
13296
13297    /**
13298     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13299     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13300     */
13301    private ProcessRecord findAppProcess(IBinder app, String reason) {
13302        if (app == null) {
13303            return null;
13304        }
13305
13306        synchronized (this) {
13307            final int NP = mProcessNames.getMap().size();
13308            for (int ip=0; ip<NP; ip++) {
13309                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13310                final int NA = apps.size();
13311                for (int ia=0; ia<NA; ia++) {
13312                    ProcessRecord p = apps.valueAt(ia);
13313                    if (p.thread != null && p.thread.asBinder() == app) {
13314                        return p;
13315                    }
13316                }
13317            }
13318
13319            Slog.w(TAG, "Can't find mystery application for " + reason
13320                    + " from pid=" + Binder.getCallingPid()
13321                    + " uid=" + Binder.getCallingUid() + ": " + app);
13322            return null;
13323        }
13324    }
13325
13326    /**
13327     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13328     * to append various headers to the dropbox log text.
13329     */
13330    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13331            StringBuilder sb) {
13332        // Watchdog thread ends up invoking this function (with
13333        // a null ProcessRecord) to add the stack file to dropbox.
13334        // Do not acquire a lock on this (am) in such cases, as it
13335        // could cause a potential deadlock, if and when watchdog
13336        // is invoked due to unavailability of lock on am and it
13337        // would prevent watchdog from killing system_server.
13338        if (process == null) {
13339            sb.append("Process: ").append(processName).append("\n");
13340            return;
13341        }
13342        // Note: ProcessRecord 'process' is guarded by the service
13343        // instance.  (notably process.pkgList, which could otherwise change
13344        // concurrently during execution of this method)
13345        synchronized (this) {
13346            sb.append("Process: ").append(processName).append("\n");
13347            int flags = process.info.flags;
13348            IPackageManager pm = AppGlobals.getPackageManager();
13349            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
13350            for (int ip=0; ip<process.pkgList.size(); ip++) {
13351                String pkg = process.pkgList.keyAt(ip);
13352                sb.append("Package: ").append(pkg);
13353                try {
13354                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13355                    if (pi != null) {
13356                        sb.append(" v").append(pi.versionCode);
13357                        if (pi.versionName != null) {
13358                            sb.append(" (").append(pi.versionName).append(")");
13359                        }
13360                    }
13361                } catch (RemoteException e) {
13362                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13363                }
13364                sb.append("\n");
13365            }
13366        }
13367    }
13368
13369    private static String processClass(ProcessRecord process) {
13370        if (process == null || process.pid == MY_PID) {
13371            return "system_server";
13372        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13373            return "system_app";
13374        } else {
13375            return "data_app";
13376        }
13377    }
13378
13379    private volatile long mWtfClusterStart;
13380    private volatile int mWtfClusterCount;
13381
13382    /**
13383     * Write a description of an error (crash, WTF, ANR) to the drop box.
13384     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13385     * @param process which caused the error, null means the system server
13386     * @param activity which triggered the error, null if unknown
13387     * @param parent activity related to the error, null if unknown
13388     * @param subject line related to the error, null if absent
13389     * @param report in long form describing the error, null if absent
13390     * @param logFile to include in the report, null if none
13391     * @param crashInfo giving an application stack trace, null if absent
13392     */
13393    public void addErrorToDropBox(String eventType,
13394            ProcessRecord process, String processName, ActivityRecord activity,
13395            ActivityRecord parent, String subject,
13396            final String report, final File logFile,
13397            final ApplicationErrorReport.CrashInfo crashInfo) {
13398        // NOTE -- this must never acquire the ActivityManagerService lock,
13399        // otherwise the watchdog may be prevented from resetting the system.
13400
13401        final String dropboxTag = processClass(process) + "_" + eventType;
13402        final DropBoxManager dbox = (DropBoxManager)
13403                mContext.getSystemService(Context.DROPBOX_SERVICE);
13404
13405        // Exit early if the dropbox isn't configured to accept this report type.
13406        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13407
13408        // Rate-limit how often we're willing to do the heavy lifting below to
13409        // collect and record logs; currently 5 logs per 10 second period.
13410        final long now = SystemClock.elapsedRealtime();
13411        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13412            mWtfClusterStart = now;
13413            mWtfClusterCount = 1;
13414        } else {
13415            if (mWtfClusterCount++ >= 5) return;
13416        }
13417
13418        final StringBuilder sb = new StringBuilder(1024);
13419        appendDropBoxProcessHeaders(process, processName, sb);
13420        if (process != null) {
13421            sb.append("Foreground: ")
13422                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13423                    .append("\n");
13424        }
13425        if (activity != null) {
13426            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13427        }
13428        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13429            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13430        }
13431        if (parent != null && parent != activity) {
13432            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13433        }
13434        if (subject != null) {
13435            sb.append("Subject: ").append(subject).append("\n");
13436        }
13437        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13438        if (Debug.isDebuggerConnected()) {
13439            sb.append("Debugger: Connected\n");
13440        }
13441        sb.append("\n");
13442
13443        // Do the rest in a worker thread to avoid blocking the caller on I/O
13444        // (After this point, we shouldn't access AMS internal data structures.)
13445        Thread worker = new Thread("Error dump: " + dropboxTag) {
13446            @Override
13447            public void run() {
13448                if (report != null) {
13449                    sb.append(report);
13450                }
13451                if (logFile != null) {
13452                    try {
13453                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
13454                                    "\n\n[[TRUNCATED]]"));
13455                    } catch (IOException e) {
13456                        Slog.e(TAG, "Error reading " + logFile, e);
13457                    }
13458                }
13459                if (crashInfo != null && crashInfo.stackTrace != null) {
13460                    sb.append(crashInfo.stackTrace);
13461                }
13462
13463                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13464                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13465                if (lines > 0) {
13466                    sb.append("\n");
13467
13468                    // Merge several logcat streams, and take the last N lines
13469                    InputStreamReader input = null;
13470                    try {
13471                        java.lang.Process logcat = new ProcessBuilder(
13472                                "/system/bin/timeout", "-k", "15s", "10s",
13473                                "/system/bin/logcat", "-v", "time", "-b", "events", "-b", "system",
13474                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13475                                        .redirectErrorStream(true).start();
13476
13477                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13478                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13479                        input = new InputStreamReader(logcat.getInputStream());
13480
13481                        int num;
13482                        char[] buf = new char[8192];
13483                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13484                    } catch (IOException e) {
13485                        Slog.e(TAG, "Error running logcat", e);
13486                    } finally {
13487                        if (input != null) try { input.close(); } catch (IOException e) {}
13488                    }
13489                }
13490
13491                dbox.addText(dropboxTag, sb.toString());
13492            }
13493        };
13494
13495        if (process == null) {
13496            // If process is null, we are being called from some internal code
13497            // and may be about to die -- run this synchronously.
13498            worker.run();
13499        } else {
13500            worker.start();
13501        }
13502    }
13503
13504    @Override
13505    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13506        enforceNotIsolatedCaller("getProcessesInErrorState");
13507        // assume our apps are happy - lazy create the list
13508        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13509
13510        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13511                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13512        int userId = UserHandle.getUserId(Binder.getCallingUid());
13513
13514        synchronized (this) {
13515
13516            // iterate across all processes
13517            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13518                ProcessRecord app = mLruProcesses.get(i);
13519                if (!allUsers && app.userId != userId) {
13520                    continue;
13521                }
13522                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13523                    // This one's in trouble, so we'll generate a report for it
13524                    // crashes are higher priority (in case there's a crash *and* an anr)
13525                    ActivityManager.ProcessErrorStateInfo report = null;
13526                    if (app.crashing) {
13527                        report = app.crashingReport;
13528                    } else if (app.notResponding) {
13529                        report = app.notRespondingReport;
13530                    }
13531
13532                    if (report != null) {
13533                        if (errList == null) {
13534                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13535                        }
13536                        errList.add(report);
13537                    } else {
13538                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13539                                " crashing = " + app.crashing +
13540                                " notResponding = " + app.notResponding);
13541                    }
13542                }
13543            }
13544        }
13545
13546        return errList;
13547    }
13548
13549    static int procStateToImportance(int procState, int memAdj,
13550            ActivityManager.RunningAppProcessInfo currApp) {
13551        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13552        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13553            currApp.lru = memAdj;
13554        } else {
13555            currApp.lru = 0;
13556        }
13557        return imp;
13558    }
13559
13560    private void fillInProcMemInfo(ProcessRecord app,
13561            ActivityManager.RunningAppProcessInfo outInfo) {
13562        outInfo.pid = app.pid;
13563        outInfo.uid = app.info.uid;
13564        if (mHeavyWeightProcess == app) {
13565            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13566        }
13567        if (app.persistent) {
13568            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13569        }
13570        if (app.activities.size() > 0) {
13571            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13572        }
13573        outInfo.lastTrimLevel = app.trimMemoryLevel;
13574        int adj = app.curAdj;
13575        int procState = app.curProcState;
13576        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13577        outInfo.importanceReasonCode = app.adjTypeCode;
13578        outInfo.processState = app.curProcState;
13579    }
13580
13581    @Override
13582    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13583        enforceNotIsolatedCaller("getRunningAppProcesses");
13584
13585        final int callingUid = Binder.getCallingUid();
13586
13587        // Lazy instantiation of list
13588        List<ActivityManager.RunningAppProcessInfo> runList = null;
13589        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13590                callingUid) == PackageManager.PERMISSION_GRANTED;
13591        final int userId = UserHandle.getUserId(callingUid);
13592        final boolean allUids = isGetTasksAllowed(
13593                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13594
13595        synchronized (this) {
13596            // Iterate across all processes
13597            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13598                ProcessRecord app = mLruProcesses.get(i);
13599                if ((!allUsers && app.userId != userId)
13600                        || (!allUids && app.uid != callingUid)) {
13601                    continue;
13602                }
13603                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13604                    // Generate process state info for running application
13605                    ActivityManager.RunningAppProcessInfo currApp =
13606                        new ActivityManager.RunningAppProcessInfo(app.processName,
13607                                app.pid, app.getPackageList());
13608                    fillInProcMemInfo(app, currApp);
13609                    if (app.adjSource instanceof ProcessRecord) {
13610                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13611                        currApp.importanceReasonImportance =
13612                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13613                                        app.adjSourceProcState);
13614                    } else if (app.adjSource instanceof ActivityRecord) {
13615                        ActivityRecord r = (ActivityRecord)app.adjSource;
13616                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13617                    }
13618                    if (app.adjTarget instanceof ComponentName) {
13619                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13620                    }
13621                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13622                    //        + " lru=" + currApp.lru);
13623                    if (runList == null) {
13624                        runList = new ArrayList<>();
13625                    }
13626                    runList.add(currApp);
13627                }
13628            }
13629        }
13630        return runList;
13631    }
13632
13633    @Override
13634    public List<ApplicationInfo> getRunningExternalApplications() {
13635        enforceNotIsolatedCaller("getRunningExternalApplications");
13636        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13637        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13638        if (runningApps != null && runningApps.size() > 0) {
13639            Set<String> extList = new HashSet<String>();
13640            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13641                if (app.pkgList != null) {
13642                    for (String pkg : app.pkgList) {
13643                        extList.add(pkg);
13644                    }
13645                }
13646            }
13647            IPackageManager pm = AppGlobals.getPackageManager();
13648            for (String pkg : extList) {
13649                try {
13650                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13651                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13652                        retList.add(info);
13653                    }
13654                } catch (RemoteException e) {
13655                }
13656            }
13657        }
13658        return retList;
13659    }
13660
13661    @Override
13662    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13663        enforceNotIsolatedCaller("getMyMemoryState");
13664        synchronized (this) {
13665            ProcessRecord proc;
13666            synchronized (mPidsSelfLocked) {
13667                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13668            }
13669            fillInProcMemInfo(proc, outInfo);
13670        }
13671    }
13672
13673    @Override
13674    public int getMemoryTrimLevel() {
13675        enforceNotIsolatedCaller("getMyMemoryState");
13676        synchronized (this) {
13677            return mLastMemoryLevel;
13678        }
13679    }
13680
13681    @Override
13682    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13683            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13684        (new ActivityManagerShellCommand(this, false)).exec(
13685                this, in, out, err, args, resultReceiver);
13686    }
13687
13688    @Override
13689    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13690        if (checkCallingPermission(android.Manifest.permission.DUMP)
13691                != PackageManager.PERMISSION_GRANTED) {
13692            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13693                    + Binder.getCallingPid()
13694                    + ", uid=" + Binder.getCallingUid()
13695                    + " without permission "
13696                    + android.Manifest.permission.DUMP);
13697            return;
13698        }
13699
13700        boolean dumpAll = false;
13701        boolean dumpClient = false;
13702        String dumpPackage = null;
13703
13704        int opti = 0;
13705        while (opti < args.length) {
13706            String opt = args[opti];
13707            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13708                break;
13709            }
13710            opti++;
13711            if ("-a".equals(opt)) {
13712                dumpAll = true;
13713            } else if ("-c".equals(opt)) {
13714                dumpClient = true;
13715            } else if ("-p".equals(opt)) {
13716                if (opti < args.length) {
13717                    dumpPackage = args[opti];
13718                    opti++;
13719                } else {
13720                    pw.println("Error: -p option requires package argument");
13721                    return;
13722                }
13723                dumpClient = true;
13724            } else if ("-h".equals(opt)) {
13725                ActivityManagerShellCommand.dumpHelp(pw, true);
13726                return;
13727            } else {
13728                pw.println("Unknown argument: " + opt + "; use -h for help");
13729            }
13730        }
13731
13732        long origId = Binder.clearCallingIdentity();
13733        boolean more = false;
13734        // Is the caller requesting to dump a particular piece of data?
13735        if (opti < args.length) {
13736            String cmd = args[opti];
13737            opti++;
13738            if ("activities".equals(cmd) || "a".equals(cmd)) {
13739                synchronized (this) {
13740                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13741                }
13742            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13743                synchronized (this) {
13744                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13745                }
13746            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13747                String[] newArgs;
13748                String name;
13749                if (opti >= args.length) {
13750                    name = null;
13751                    newArgs = EMPTY_STRING_ARRAY;
13752                } else {
13753                    dumpPackage = args[opti];
13754                    opti++;
13755                    newArgs = new String[args.length - opti];
13756                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13757                            args.length - opti);
13758                }
13759                synchronized (this) {
13760                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13761                }
13762            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13763                String[] newArgs;
13764                String name;
13765                if (opti >= args.length) {
13766                    name = null;
13767                    newArgs = EMPTY_STRING_ARRAY;
13768                } else {
13769                    dumpPackage = args[opti];
13770                    opti++;
13771                    newArgs = new String[args.length - opti];
13772                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13773                            args.length - opti);
13774                }
13775                synchronized (this) {
13776                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13777                }
13778            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13779                String[] newArgs;
13780                String name;
13781                if (opti >= args.length) {
13782                    name = null;
13783                    newArgs = EMPTY_STRING_ARRAY;
13784                } else {
13785                    dumpPackage = args[opti];
13786                    opti++;
13787                    newArgs = new String[args.length - opti];
13788                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13789                            args.length - opti);
13790                }
13791                synchronized (this) {
13792                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13793                }
13794            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13795                synchronized (this) {
13796                    dumpOomLocked(fd, pw, args, opti, true);
13797                }
13798            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13799                synchronized (this) {
13800                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
13801                }
13802            } else if ("provider".equals(cmd)) {
13803                String[] newArgs;
13804                String name;
13805                if (opti >= args.length) {
13806                    name = null;
13807                    newArgs = EMPTY_STRING_ARRAY;
13808                } else {
13809                    name = args[opti];
13810                    opti++;
13811                    newArgs = new String[args.length - opti];
13812                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13813                }
13814                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13815                    pw.println("No providers match: " + name);
13816                    pw.println("Use -h for help.");
13817                }
13818            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13819                synchronized (this) {
13820                    dumpProvidersLocked(fd, pw, args, opti, true, null);
13821                }
13822            } else if ("service".equals(cmd)) {
13823                String[] newArgs;
13824                String name;
13825                if (opti >= args.length) {
13826                    name = null;
13827                    newArgs = EMPTY_STRING_ARRAY;
13828                } else {
13829                    name = args[opti];
13830                    opti++;
13831                    newArgs = new String[args.length - opti];
13832                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13833                            args.length - opti);
13834                }
13835                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13836                    pw.println("No services match: " + name);
13837                    pw.println("Use -h for help.");
13838                }
13839            } else if ("package".equals(cmd)) {
13840                String[] newArgs;
13841                if (opti >= args.length) {
13842                    pw.println("package: no package name specified");
13843                    pw.println("Use -h for help.");
13844                } else {
13845                    dumpPackage = args[opti];
13846                    opti++;
13847                    newArgs = new String[args.length - opti];
13848                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13849                            args.length - opti);
13850                    args = newArgs;
13851                    opti = 0;
13852                    more = true;
13853                }
13854            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13855                synchronized (this) {
13856                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13857                }
13858            } else if ("services".equals(cmd) || "s".equals(cmd)) {
13859                if (dumpClient) {
13860                    ActiveServices.ServiceDumper dumper;
13861                    synchronized (this) {
13862                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
13863                                dumpPackage);
13864                    }
13865                    dumper.dumpWithClient();
13866                } else {
13867                    synchronized (this) {
13868                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
13869                                dumpPackage).dumpLocked();
13870                    }
13871                }
13872            } else if ("locks".equals(cmd)) {
13873                LockGuard.dump(fd, pw, args);
13874            } else {
13875                // Dumping a single activity?
13876                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13877                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
13878                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
13879                    if (res < 0) {
13880                        pw.println("Bad activity command, or no activities match: " + cmd);
13881                        pw.println("Use -h for help.");
13882                    }
13883                }
13884            }
13885            if (!more) {
13886                Binder.restoreCallingIdentity(origId);
13887                return;
13888            }
13889        }
13890
13891        // No piece of data specified, dump everything.
13892        if (dumpClient) {
13893            ActiveServices.ServiceDumper sdumper;
13894            synchronized (this) {
13895                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13896                pw.println();
13897                if (dumpAll) {
13898                    pw.println("-------------------------------------------------------------------------------");
13899                }
13900                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13901                pw.println();
13902                if (dumpAll) {
13903                    pw.println("-------------------------------------------------------------------------------");
13904                }
13905                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13906                pw.println();
13907                if (dumpAll) {
13908                    pw.println("-------------------------------------------------------------------------------");
13909                }
13910                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13911                pw.println();
13912                if (dumpAll) {
13913                    pw.println("-------------------------------------------------------------------------------");
13914                }
13915                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
13916                        dumpPackage);
13917            }
13918            sdumper.dumpWithClient();
13919            pw.println();
13920            synchronized (this) {
13921                if (dumpAll) {
13922                    pw.println("-------------------------------------------------------------------------------");
13923                }
13924                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13925                pw.println();
13926                if (dumpAll) {
13927                    pw.println("-------------------------------------------------------------------------------");
13928                }
13929                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13930                if (mAssociations.size() > 0) {
13931                    pw.println();
13932                    if (dumpAll) {
13933                        pw.println("-------------------------------------------------------------------------------");
13934                    }
13935                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13936                }
13937                pw.println();
13938                if (dumpAll) {
13939                    pw.println("-------------------------------------------------------------------------------");
13940                }
13941                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13942            }
13943
13944        } else {
13945            synchronized (this) {
13946                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13947                pw.println();
13948                if (dumpAll) {
13949                    pw.println("-------------------------------------------------------------------------------");
13950                }
13951                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13952                pw.println();
13953                if (dumpAll) {
13954                    pw.println("-------------------------------------------------------------------------------");
13955                }
13956                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13957                pw.println();
13958                if (dumpAll) {
13959                    pw.println("-------------------------------------------------------------------------------");
13960                }
13961                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13962                pw.println();
13963                if (dumpAll) {
13964                    pw.println("-------------------------------------------------------------------------------");
13965                }
13966                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
13967                        .dumpLocked();
13968                pw.println();
13969                if (dumpAll) {
13970                    pw.println("-------------------------------------------------------------------------------");
13971                }
13972                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13973                pw.println();
13974                if (dumpAll) {
13975                    pw.println("-------------------------------------------------------------------------------");
13976                }
13977                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13978                if (mAssociations.size() > 0) {
13979                    pw.println();
13980                    if (dumpAll) {
13981                        pw.println("-------------------------------------------------------------------------------");
13982                    }
13983                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13984                }
13985                pw.println();
13986                if (dumpAll) {
13987                    pw.println("-------------------------------------------------------------------------------");
13988                }
13989                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13990            }
13991        }
13992        Binder.restoreCallingIdentity(origId);
13993    }
13994
13995    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13996            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13997        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
13998
13999        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
14000                dumpPackage);
14001        boolean needSep = printedAnything;
14002
14003        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
14004                dumpPackage, needSep, "  mFocusedActivity: ");
14005        if (printed) {
14006            printedAnything = true;
14007            needSep = false;
14008        }
14009
14010        if (dumpPackage == null) {
14011            if (needSep) {
14012                pw.println();
14013            }
14014            needSep = true;
14015            printedAnything = true;
14016            mStackSupervisor.dump(pw, "  ");
14017        }
14018
14019        if (!printedAnything) {
14020            pw.println("  (nothing)");
14021        }
14022    }
14023
14024    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14025            int opti, boolean dumpAll, String dumpPackage) {
14026        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14027
14028        boolean printedAnything = false;
14029
14030        if (mRecentTasks != null && mRecentTasks.size() > 0) {
14031            boolean printedHeader = false;
14032
14033            final int N = mRecentTasks.size();
14034            for (int i=0; i<N; i++) {
14035                TaskRecord tr = mRecentTasks.get(i);
14036                if (dumpPackage != null) {
14037                    if (tr.realActivity == null ||
14038                            !dumpPackage.equals(tr.realActivity)) {
14039                        continue;
14040                    }
14041                }
14042                if (!printedHeader) {
14043                    pw.println("  Recent tasks:");
14044                    printedHeader = true;
14045                    printedAnything = true;
14046                }
14047                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
14048                        pw.println(tr);
14049                if (dumpAll) {
14050                    mRecentTasks.get(i).dump(pw, "    ");
14051                }
14052            }
14053        }
14054
14055        if (!printedAnything) {
14056            pw.println("  (nothing)");
14057        }
14058    }
14059
14060    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14061            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14062        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14063
14064        int dumpUid = 0;
14065        if (dumpPackage != null) {
14066            IPackageManager pm = AppGlobals.getPackageManager();
14067            try {
14068                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
14069            } catch (RemoteException e) {
14070            }
14071        }
14072
14073        boolean printedAnything = false;
14074
14075        final long now = SystemClock.uptimeMillis();
14076
14077        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14078            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14079                    = mAssociations.valueAt(i1);
14080            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14081                SparseArray<ArrayMap<String, Association>> sourceUids
14082                        = targetComponents.valueAt(i2);
14083                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14084                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14085                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14086                        Association ass = sourceProcesses.valueAt(i4);
14087                        if (dumpPackage != null) {
14088                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14089                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14090                                continue;
14091                            }
14092                        }
14093                        printedAnything = true;
14094                        pw.print("  ");
14095                        pw.print(ass.mTargetProcess);
14096                        pw.print("/");
14097                        UserHandle.formatUid(pw, ass.mTargetUid);
14098                        pw.print(" <- ");
14099                        pw.print(ass.mSourceProcess);
14100                        pw.print("/");
14101                        UserHandle.formatUid(pw, ass.mSourceUid);
14102                        pw.println();
14103                        pw.print("    via ");
14104                        pw.print(ass.mTargetComponent.flattenToShortString());
14105                        pw.println();
14106                        pw.print("    ");
14107                        long dur = ass.mTime;
14108                        if (ass.mNesting > 0) {
14109                            dur += now - ass.mStartTime;
14110                        }
14111                        TimeUtils.formatDuration(dur, pw);
14112                        pw.print(" (");
14113                        pw.print(ass.mCount);
14114                        pw.print(" times)");
14115                        pw.print("  ");
14116                        for (int i=0; i<ass.mStateTimes.length; i++) {
14117                            long amt = ass.mStateTimes[i];
14118                            if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14119                                amt += now - ass.mLastStateUptime;
14120                            }
14121                            if (amt != 0) {
14122                                pw.print(" ");
14123                                pw.print(ProcessList.makeProcStateString(
14124                                            i + ActivityManager.MIN_PROCESS_STATE));
14125                                pw.print("=");
14126                                TimeUtils.formatDuration(amt, pw);
14127                                if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14128                                    pw.print("*");
14129                                }
14130                            }
14131                        }
14132                        pw.println();
14133                        if (ass.mNesting > 0) {
14134                            pw.print("    Currently active: ");
14135                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
14136                            pw.println();
14137                        }
14138                    }
14139                }
14140            }
14141
14142        }
14143
14144        if (!printedAnything) {
14145            pw.println("  (nothing)");
14146        }
14147    }
14148
14149    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14150            String header, boolean needSep) {
14151        boolean printed = false;
14152        int whichAppId = -1;
14153        if (dumpPackage != null) {
14154            try {
14155                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14156                        dumpPackage, 0);
14157                whichAppId = UserHandle.getAppId(info.uid);
14158            } catch (NameNotFoundException e) {
14159                e.printStackTrace();
14160            }
14161        }
14162        for (int i=0; i<uids.size(); i++) {
14163            UidRecord uidRec = uids.valueAt(i);
14164            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14165                continue;
14166            }
14167            if (!printed) {
14168                printed = true;
14169                if (needSep) {
14170                    pw.println();
14171                }
14172                pw.print("  ");
14173                pw.println(header);
14174                needSep = true;
14175            }
14176            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14177            pw.print(": "); pw.println(uidRec);
14178        }
14179        return printed;
14180    }
14181
14182    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14183            int opti, boolean dumpAll, String dumpPackage) {
14184        boolean needSep = false;
14185        boolean printedAnything = false;
14186        int numPers = 0;
14187
14188        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14189
14190        if (dumpAll) {
14191            final int NP = mProcessNames.getMap().size();
14192            for (int ip=0; ip<NP; ip++) {
14193                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14194                final int NA = procs.size();
14195                for (int ia=0; ia<NA; ia++) {
14196                    ProcessRecord r = procs.valueAt(ia);
14197                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14198                        continue;
14199                    }
14200                    if (!needSep) {
14201                        pw.println("  All known processes:");
14202                        needSep = true;
14203                        printedAnything = true;
14204                    }
14205                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14206                        pw.print(" UID "); pw.print(procs.keyAt(ia));
14207                        pw.print(" "); pw.println(r);
14208                    r.dump(pw, "    ");
14209                    if (r.persistent) {
14210                        numPers++;
14211                    }
14212                }
14213            }
14214        }
14215
14216        if (mIsolatedProcesses.size() > 0) {
14217            boolean printed = false;
14218            for (int i=0; i<mIsolatedProcesses.size(); i++) {
14219                ProcessRecord r = mIsolatedProcesses.valueAt(i);
14220                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14221                    continue;
14222                }
14223                if (!printed) {
14224                    if (needSep) {
14225                        pw.println();
14226                    }
14227                    pw.println("  Isolated process list (sorted by uid):");
14228                    printedAnything = true;
14229                    printed = true;
14230                    needSep = true;
14231                }
14232                pw.println(String.format("%sIsolated #%2d: %s",
14233                        "    ", i, r.toString()));
14234            }
14235        }
14236
14237        if (mActiveUids.size() > 0) {
14238            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14239                printedAnything = needSep = true;
14240            }
14241        }
14242        if (mValidateUids.size() > 0) {
14243            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14244                printedAnything = needSep = true;
14245            }
14246        }
14247
14248        if (mLruProcesses.size() > 0) {
14249            if (needSep) {
14250                pw.println();
14251            }
14252            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14253                    pw.print(" total, non-act at ");
14254                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14255                    pw.print(", non-svc at ");
14256                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14257                    pw.println("):");
14258            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14259            needSep = true;
14260            printedAnything = true;
14261        }
14262
14263        if (dumpAll || dumpPackage != null) {
14264            synchronized (mPidsSelfLocked) {
14265                boolean printed = false;
14266                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14267                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14268                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14269                        continue;
14270                    }
14271                    if (!printed) {
14272                        if (needSep) pw.println();
14273                        needSep = true;
14274                        pw.println("  PID mappings:");
14275                        printed = true;
14276                        printedAnything = true;
14277                    }
14278                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14279                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14280                }
14281            }
14282        }
14283
14284        if (mForegroundProcesses.size() > 0) {
14285            synchronized (mPidsSelfLocked) {
14286                boolean printed = false;
14287                for (int i=0; i<mForegroundProcesses.size(); i++) {
14288                    ProcessRecord r = mPidsSelfLocked.get(
14289                            mForegroundProcesses.valueAt(i).pid);
14290                    if (dumpPackage != null && (r == null
14291                            || !r.pkgList.containsKey(dumpPackage))) {
14292                        continue;
14293                    }
14294                    if (!printed) {
14295                        if (needSep) pw.println();
14296                        needSep = true;
14297                        pw.println("  Foreground Processes:");
14298                        printed = true;
14299                        printedAnything = true;
14300                    }
14301                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14302                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14303                }
14304            }
14305        }
14306
14307        if (mPersistentStartingProcesses.size() > 0) {
14308            if (needSep) pw.println();
14309            needSep = true;
14310            printedAnything = true;
14311            pw.println("  Persisent processes that are starting:");
14312            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14313                    "Starting Norm", "Restarting PERS", dumpPackage);
14314        }
14315
14316        if (mRemovedProcesses.size() > 0) {
14317            if (needSep) pw.println();
14318            needSep = true;
14319            printedAnything = true;
14320            pw.println("  Processes that are being removed:");
14321            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14322                    "Removed Norm", "Removed PERS", dumpPackage);
14323        }
14324
14325        if (mProcessesOnHold.size() > 0) {
14326            if (needSep) pw.println();
14327            needSep = true;
14328            printedAnything = true;
14329            pw.println("  Processes that are on old until the system is ready:");
14330            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14331                    "OnHold Norm", "OnHold PERS", dumpPackage);
14332        }
14333
14334        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14335
14336        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14337        if (needSep) {
14338            printedAnything = true;
14339        }
14340
14341        if (dumpPackage == null) {
14342            pw.println();
14343            needSep = false;
14344            mUserController.dump(pw, dumpAll);
14345        }
14346        if (mHomeProcess != null && (dumpPackage == null
14347                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14348            if (needSep) {
14349                pw.println();
14350                needSep = false;
14351            }
14352            pw.println("  mHomeProcess: " + mHomeProcess);
14353        }
14354        if (mPreviousProcess != null && (dumpPackage == null
14355                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14356            if (needSep) {
14357                pw.println();
14358                needSep = false;
14359            }
14360            pw.println("  mPreviousProcess: " + mPreviousProcess);
14361        }
14362        if (dumpAll) {
14363            StringBuilder sb = new StringBuilder(128);
14364            sb.append("  mPreviousProcessVisibleTime: ");
14365            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14366            pw.println(sb);
14367        }
14368        if (mHeavyWeightProcess != null && (dumpPackage == null
14369                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14370            if (needSep) {
14371                pw.println();
14372                needSep = false;
14373            }
14374            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14375        }
14376        if (dumpPackage == null) {
14377            pw.println("  mConfiguration: " + mConfiguration);
14378        }
14379        if (dumpAll) {
14380            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14381            if (mCompatModePackages.getPackages().size() > 0) {
14382                boolean printed = false;
14383                for (Map.Entry<String, Integer> entry
14384                        : mCompatModePackages.getPackages().entrySet()) {
14385                    String pkg = entry.getKey();
14386                    int mode = entry.getValue();
14387                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14388                        continue;
14389                    }
14390                    if (!printed) {
14391                        pw.println("  mScreenCompatPackages:");
14392                        printed = true;
14393                    }
14394                    pw.print("    "); pw.print(pkg); pw.print(": ");
14395                            pw.print(mode); pw.println();
14396                }
14397            }
14398        }
14399        if (dumpPackage == null) {
14400            pw.println("  mWakefulness="
14401                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14402            pw.println("  mSleepTokens=" + mSleepTokens);
14403            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14404                    + lockScreenShownToString());
14405            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14406            if (mRunningVoice != null) {
14407                pw.println("  mRunningVoice=" + mRunningVoice);
14408                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14409            }
14410        }
14411        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14412                || mOrigWaitForDebugger) {
14413            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14414                    || dumpPackage.equals(mOrigDebugApp)) {
14415                if (needSep) {
14416                    pw.println();
14417                    needSep = false;
14418                }
14419                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14420                        + " mDebugTransient=" + mDebugTransient
14421                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14422            }
14423        }
14424        if (mCurAppTimeTracker != null) {
14425            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14426        }
14427        if (mMemWatchProcesses.getMap().size() > 0) {
14428            pw.println("  Mem watch processes:");
14429            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14430                    = mMemWatchProcesses.getMap();
14431            for (int i=0; i<procs.size(); i++) {
14432                final String proc = procs.keyAt(i);
14433                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14434                for (int j=0; j<uids.size(); j++) {
14435                    if (needSep) {
14436                        pw.println();
14437                        needSep = false;
14438                    }
14439                    StringBuilder sb = new StringBuilder();
14440                    sb.append("    ").append(proc).append('/');
14441                    UserHandle.formatUid(sb, uids.keyAt(j));
14442                    Pair<Long, String> val = uids.valueAt(j);
14443                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14444                    if (val.second != null) {
14445                        sb.append(", report to ").append(val.second);
14446                    }
14447                    pw.println(sb.toString());
14448                }
14449            }
14450            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14451            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14452            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14453                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14454        }
14455        if (mTrackAllocationApp != null) {
14456            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14457                if (needSep) {
14458                    pw.println();
14459                    needSep = false;
14460                }
14461                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14462            }
14463        }
14464        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14465                || mProfileFd != null) {
14466            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14467                if (needSep) {
14468                    pw.println();
14469                    needSep = false;
14470                }
14471                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14472                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14473                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14474                        + mAutoStopProfiler);
14475                pw.println("  mProfileType=" + mProfileType);
14476            }
14477        }
14478        if (mNativeDebuggingApp != null) {
14479            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14480                if (needSep) {
14481                    pw.println();
14482                    needSep = false;
14483                }
14484                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14485            }
14486        }
14487        if (dumpPackage == null) {
14488            if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14489                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14490                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14491            }
14492            if (mController != null) {
14493                pw.println("  mController=" + mController
14494                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14495            }
14496            if (dumpAll) {
14497                pw.println("  Total persistent processes: " + numPers);
14498                pw.println("  mProcessesReady=" + mProcessesReady
14499                        + " mSystemReady=" + mSystemReady
14500                        + " mBooted=" + mBooted
14501                        + " mFactoryTest=" + mFactoryTest);
14502                pw.println("  mBooting=" + mBooting
14503                        + " mCallFinishBooting=" + mCallFinishBooting
14504                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14505                pw.print("  mLastPowerCheckRealtime=");
14506                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14507                        pw.println("");
14508                pw.print("  mLastPowerCheckUptime=");
14509                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14510                        pw.println("");
14511                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14512                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14513                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14514                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14515                        + " (" + mLruProcesses.size() + " total)"
14516                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14517                        + " mNumServiceProcs=" + mNumServiceProcs
14518                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14519                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14520                        + " mLastMemoryLevel=" + mLastMemoryLevel
14521                        + " mLastNumProcesses=" + mLastNumProcesses);
14522                long now = SystemClock.uptimeMillis();
14523                pw.print("  mLastIdleTime=");
14524                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14525                        pw.print(" mLowRamSinceLastIdle=");
14526                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14527                        pw.println();
14528            }
14529        }
14530
14531        if (!printedAnything) {
14532            pw.println("  (nothing)");
14533        }
14534    }
14535
14536    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14537            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14538        if (mProcessesToGc.size() > 0) {
14539            boolean printed = false;
14540            long now = SystemClock.uptimeMillis();
14541            for (int i=0; i<mProcessesToGc.size(); i++) {
14542                ProcessRecord proc = mProcessesToGc.get(i);
14543                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14544                    continue;
14545                }
14546                if (!printed) {
14547                    if (needSep) pw.println();
14548                    needSep = true;
14549                    pw.println("  Processes that are waiting to GC:");
14550                    printed = true;
14551                }
14552                pw.print("    Process "); pw.println(proc);
14553                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14554                        pw.print(", last gced=");
14555                        pw.print(now-proc.lastRequestedGc);
14556                        pw.print(" ms ago, last lowMem=");
14557                        pw.print(now-proc.lastLowMemory);
14558                        pw.println(" ms ago");
14559
14560            }
14561        }
14562        return needSep;
14563    }
14564
14565    void printOomLevel(PrintWriter pw, String name, int adj) {
14566        pw.print("    ");
14567        if (adj >= 0) {
14568            pw.print(' ');
14569            if (adj < 10) pw.print(' ');
14570        } else {
14571            if (adj > -10) pw.print(' ');
14572        }
14573        pw.print(adj);
14574        pw.print(": ");
14575        pw.print(name);
14576        pw.print(" (");
14577        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14578        pw.println(")");
14579    }
14580
14581    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14582            int opti, boolean dumpAll) {
14583        boolean needSep = false;
14584
14585        if (mLruProcesses.size() > 0) {
14586            if (needSep) pw.println();
14587            needSep = true;
14588            pw.println("  OOM levels:");
14589            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14590            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14591            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14592            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14593            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14594            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14595            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14596            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14597            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14598            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14599            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14600            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14601            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14602            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14603
14604            if (needSep) pw.println();
14605            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14606                    pw.print(" total, non-act at ");
14607                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14608                    pw.print(", non-svc at ");
14609                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14610                    pw.println("):");
14611            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14612            needSep = true;
14613        }
14614
14615        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14616
14617        pw.println();
14618        pw.println("  mHomeProcess: " + mHomeProcess);
14619        pw.println("  mPreviousProcess: " + mPreviousProcess);
14620        if (mHeavyWeightProcess != null) {
14621            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14622        }
14623
14624        return true;
14625    }
14626
14627    /**
14628     * There are three ways to call this:
14629     *  - no provider specified: dump all the providers
14630     *  - a flattened component name that matched an existing provider was specified as the
14631     *    first arg: dump that one provider
14632     *  - the first arg isn't the flattened component name of an existing provider:
14633     *    dump all providers whose component contains the first arg as a substring
14634     */
14635    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14636            int opti, boolean dumpAll) {
14637        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14638    }
14639
14640    static class ItemMatcher {
14641        ArrayList<ComponentName> components;
14642        ArrayList<String> strings;
14643        ArrayList<Integer> objects;
14644        boolean all;
14645
14646        ItemMatcher() {
14647            all = true;
14648        }
14649
14650        void build(String name) {
14651            ComponentName componentName = ComponentName.unflattenFromString(name);
14652            if (componentName != null) {
14653                if (components == null) {
14654                    components = new ArrayList<ComponentName>();
14655                }
14656                components.add(componentName);
14657                all = false;
14658            } else {
14659                int objectId = 0;
14660                // Not a '/' separated full component name; maybe an object ID?
14661                try {
14662                    objectId = Integer.parseInt(name, 16);
14663                    if (objects == null) {
14664                        objects = new ArrayList<Integer>();
14665                    }
14666                    objects.add(objectId);
14667                    all = false;
14668                } catch (RuntimeException e) {
14669                    // Not an integer; just do string match.
14670                    if (strings == null) {
14671                        strings = new ArrayList<String>();
14672                    }
14673                    strings.add(name);
14674                    all = false;
14675                }
14676            }
14677        }
14678
14679        int build(String[] args, int opti) {
14680            for (; opti<args.length; opti++) {
14681                String name = args[opti];
14682                if ("--".equals(name)) {
14683                    return opti+1;
14684                }
14685                build(name);
14686            }
14687            return opti;
14688        }
14689
14690        boolean match(Object object, ComponentName comp) {
14691            if (all) {
14692                return true;
14693            }
14694            if (components != null) {
14695                for (int i=0; i<components.size(); i++) {
14696                    if (components.get(i).equals(comp)) {
14697                        return true;
14698                    }
14699                }
14700            }
14701            if (objects != null) {
14702                for (int i=0; i<objects.size(); i++) {
14703                    if (System.identityHashCode(object) == objects.get(i)) {
14704                        return true;
14705                    }
14706                }
14707            }
14708            if (strings != null) {
14709                String flat = comp.flattenToString();
14710                for (int i=0; i<strings.size(); i++) {
14711                    if (flat.contains(strings.get(i))) {
14712                        return true;
14713                    }
14714                }
14715            }
14716            return false;
14717        }
14718    }
14719
14720    /**
14721     * There are three things that cmd can be:
14722     *  - a flattened component name that matches an existing activity
14723     *  - the cmd arg isn't the flattened component name of an existing activity:
14724     *    dump all activity whose component contains the cmd as a substring
14725     *  - A hex number of the ActivityRecord object instance.
14726     */
14727    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14728            int opti, boolean dumpAll) {
14729        ArrayList<ActivityRecord> activities;
14730
14731        synchronized (this) {
14732            activities = mStackSupervisor.getDumpActivitiesLocked(name);
14733        }
14734
14735        if (activities.size() <= 0) {
14736            return false;
14737        }
14738
14739        String[] newArgs = new String[args.length - opti];
14740        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14741
14742        TaskRecord lastTask = null;
14743        boolean needSep = false;
14744        for (int i=activities.size()-1; i>=0; i--) {
14745            ActivityRecord r = activities.get(i);
14746            if (needSep) {
14747                pw.println();
14748            }
14749            needSep = true;
14750            synchronized (this) {
14751                if (lastTask != r.task) {
14752                    lastTask = r.task;
14753                    pw.print("TASK "); pw.print(lastTask.affinity);
14754                            pw.print(" id="); pw.println(lastTask.taskId);
14755                    if (dumpAll) {
14756                        lastTask.dump(pw, "  ");
14757                    }
14758                }
14759            }
14760            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14761        }
14762        return true;
14763    }
14764
14765    /**
14766     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14767     * there is a thread associated with the activity.
14768     */
14769    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14770            final ActivityRecord r, String[] args, boolean dumpAll) {
14771        String innerPrefix = prefix + "  ";
14772        synchronized (this) {
14773            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14774                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14775                    pw.print(" pid=");
14776                    if (r.app != null) pw.println(r.app.pid);
14777                    else pw.println("(not running)");
14778            if (dumpAll) {
14779                r.dump(pw, innerPrefix);
14780            }
14781        }
14782        if (r.app != null && r.app.thread != null) {
14783            // flush anything that is already in the PrintWriter since the thread is going
14784            // to write to the file descriptor directly
14785            pw.flush();
14786            try {
14787                TransferPipe tp = new TransferPipe();
14788                try {
14789                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14790                            r.appToken, innerPrefix, args);
14791                    tp.go(fd);
14792                } finally {
14793                    tp.kill();
14794                }
14795            } catch (IOException e) {
14796                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14797            } catch (RemoteException e) {
14798                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14799            }
14800        }
14801    }
14802
14803    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14804            int opti, boolean dumpAll, String dumpPackage) {
14805        boolean needSep = false;
14806        boolean onlyHistory = false;
14807        boolean printedAnything = false;
14808
14809        if ("history".equals(dumpPackage)) {
14810            if (opti < args.length && "-s".equals(args[opti])) {
14811                dumpAll = false;
14812            }
14813            onlyHistory = true;
14814            dumpPackage = null;
14815        }
14816
14817        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14818        if (!onlyHistory && dumpAll) {
14819            if (mRegisteredReceivers.size() > 0) {
14820                boolean printed = false;
14821                Iterator it = mRegisteredReceivers.values().iterator();
14822                while (it.hasNext()) {
14823                    ReceiverList r = (ReceiverList)it.next();
14824                    if (dumpPackage != null && (r.app == null ||
14825                            !dumpPackage.equals(r.app.info.packageName))) {
14826                        continue;
14827                    }
14828                    if (!printed) {
14829                        pw.println("  Registered Receivers:");
14830                        needSep = true;
14831                        printed = true;
14832                        printedAnything = true;
14833                    }
14834                    pw.print("  * "); pw.println(r);
14835                    r.dump(pw, "    ");
14836                }
14837            }
14838
14839            if (mReceiverResolver.dump(pw, needSep ?
14840                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
14841                    "    ", dumpPackage, false, false)) {
14842                needSep = true;
14843                printedAnything = true;
14844            }
14845        }
14846
14847        for (BroadcastQueue q : mBroadcastQueues) {
14848            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14849            printedAnything |= needSep;
14850        }
14851
14852        needSep = true;
14853
14854        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14855            for (int user=0; user<mStickyBroadcasts.size(); user++) {
14856                if (needSep) {
14857                    pw.println();
14858                }
14859                needSep = true;
14860                printedAnything = true;
14861                pw.print("  Sticky broadcasts for user ");
14862                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14863                StringBuilder sb = new StringBuilder(128);
14864                for (Map.Entry<String, ArrayList<Intent>> ent
14865                        : mStickyBroadcasts.valueAt(user).entrySet()) {
14866                    pw.print("  * Sticky action "); pw.print(ent.getKey());
14867                    if (dumpAll) {
14868                        pw.println(":");
14869                        ArrayList<Intent> intents = ent.getValue();
14870                        final int N = intents.size();
14871                        for (int i=0; i<N; i++) {
14872                            sb.setLength(0);
14873                            sb.append("    Intent: ");
14874                            intents.get(i).toShortString(sb, false, true, false, false);
14875                            pw.println(sb.toString());
14876                            Bundle bundle = intents.get(i).getExtras();
14877                            if (bundle != null) {
14878                                pw.print("      ");
14879                                pw.println(bundle.toString());
14880                            }
14881                        }
14882                    } else {
14883                        pw.println("");
14884                    }
14885                }
14886            }
14887        }
14888
14889        if (!onlyHistory && dumpAll) {
14890            pw.println();
14891            for (BroadcastQueue queue : mBroadcastQueues) {
14892                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
14893                        + queue.mBroadcastsScheduled);
14894            }
14895            pw.println("  mHandler:");
14896            mHandler.dump(new PrintWriterPrinter(pw), "    ");
14897            needSep = true;
14898            printedAnything = true;
14899        }
14900
14901        if (!printedAnything) {
14902            pw.println("  (nothing)");
14903        }
14904    }
14905
14906    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14907            int opti, boolean dumpAll, String dumpPackage) {
14908        boolean needSep;
14909        boolean printedAnything = false;
14910
14911        ItemMatcher matcher = new ItemMatcher();
14912        matcher.build(args, opti);
14913
14914        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14915
14916        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14917        printedAnything |= needSep;
14918
14919        if (mLaunchingProviders.size() > 0) {
14920            boolean printed = false;
14921            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14922                ContentProviderRecord r = mLaunchingProviders.get(i);
14923                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14924                    continue;
14925                }
14926                if (!printed) {
14927                    if (needSep) pw.println();
14928                    needSep = true;
14929                    pw.println("  Launching content providers:");
14930                    printed = true;
14931                    printedAnything = true;
14932                }
14933                pw.print("  Launching #"); pw.print(i); pw.print(": ");
14934                        pw.println(r);
14935            }
14936        }
14937
14938        if (!printedAnything) {
14939            pw.println("  (nothing)");
14940        }
14941    }
14942
14943    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14944            int opti, boolean dumpAll, String dumpPackage) {
14945        boolean needSep = false;
14946        boolean printedAnything = false;
14947
14948        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
14949
14950        if (mGrantedUriPermissions.size() > 0) {
14951            boolean printed = false;
14952            int dumpUid = -2;
14953            if (dumpPackage != null) {
14954                try {
14955                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
14956                            MATCH_UNINSTALLED_PACKAGES, 0);
14957                } catch (NameNotFoundException e) {
14958                    dumpUid = -1;
14959                }
14960            }
14961            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14962                int uid = mGrantedUriPermissions.keyAt(i);
14963                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14964                    continue;
14965                }
14966                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14967                if (!printed) {
14968                    if (needSep) pw.println();
14969                    needSep = true;
14970                    pw.println("  Granted Uri Permissions:");
14971                    printed = true;
14972                    printedAnything = true;
14973                }
14974                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
14975                for (UriPermission perm : perms.values()) {
14976                    pw.print("    "); pw.println(perm);
14977                    if (dumpAll) {
14978                        perm.dump(pw, "      ");
14979                    }
14980                }
14981            }
14982        }
14983
14984        if (!printedAnything) {
14985            pw.println("  (nothing)");
14986        }
14987    }
14988
14989    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14990            int opti, boolean dumpAll, String dumpPackage) {
14991        boolean printed = false;
14992
14993        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
14994
14995        if (mIntentSenderRecords.size() > 0) {
14996            Iterator<WeakReference<PendingIntentRecord>> it
14997                    = mIntentSenderRecords.values().iterator();
14998            while (it.hasNext()) {
14999                WeakReference<PendingIntentRecord> ref = it.next();
15000                PendingIntentRecord rec = ref != null ? ref.get(): null;
15001                if (dumpPackage != null && (rec == null
15002                        || !dumpPackage.equals(rec.key.packageName))) {
15003                    continue;
15004                }
15005                printed = true;
15006                if (rec != null) {
15007                    pw.print("  * "); pw.println(rec);
15008                    if (dumpAll) {
15009                        rec.dump(pw, "    ");
15010                    }
15011                } else {
15012                    pw.print("  * "); pw.println(ref);
15013                }
15014            }
15015        }
15016
15017        if (!printed) {
15018            pw.println("  (nothing)");
15019        }
15020    }
15021
15022    private static final int dumpProcessList(PrintWriter pw,
15023            ActivityManagerService service, List list,
15024            String prefix, String normalLabel, String persistentLabel,
15025            String dumpPackage) {
15026        int numPers = 0;
15027        final int N = list.size()-1;
15028        for (int i=N; i>=0; i--) {
15029            ProcessRecord r = (ProcessRecord)list.get(i);
15030            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15031                continue;
15032            }
15033            pw.println(String.format("%s%s #%2d: %s",
15034                    prefix, (r.persistent ? persistentLabel : normalLabel),
15035                    i, r.toString()));
15036            if (r.persistent) {
15037                numPers++;
15038            }
15039        }
15040        return numPers;
15041    }
15042
15043    private static final boolean dumpProcessOomList(PrintWriter pw,
15044            ActivityManagerService service, List<ProcessRecord> origList,
15045            String prefix, String normalLabel, String persistentLabel,
15046            boolean inclDetails, String dumpPackage) {
15047
15048        ArrayList<Pair<ProcessRecord, Integer>> list
15049                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15050        for (int i=0; i<origList.size(); i++) {
15051            ProcessRecord r = origList.get(i);
15052            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15053                continue;
15054            }
15055            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15056        }
15057
15058        if (list.size() <= 0) {
15059            return false;
15060        }
15061
15062        Comparator<Pair<ProcessRecord, Integer>> comparator
15063                = new Comparator<Pair<ProcessRecord, Integer>>() {
15064            @Override
15065            public int compare(Pair<ProcessRecord, Integer> object1,
15066                    Pair<ProcessRecord, Integer> object2) {
15067                if (object1.first.setAdj != object2.first.setAdj) {
15068                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15069                }
15070                if (object1.first.setProcState != object2.first.setProcState) {
15071                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15072                }
15073                if (object1.second.intValue() != object2.second.intValue()) {
15074                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15075                }
15076                return 0;
15077            }
15078        };
15079
15080        Collections.sort(list, comparator);
15081
15082        final long curRealtime = SystemClock.elapsedRealtime();
15083        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15084        final long curUptime = SystemClock.uptimeMillis();
15085        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15086
15087        for (int i=list.size()-1; i>=0; i--) {
15088            ProcessRecord r = list.get(i).first;
15089            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15090            char schedGroup;
15091            switch (r.setSchedGroup) {
15092                case ProcessList.SCHED_GROUP_BACKGROUND:
15093                    schedGroup = 'B';
15094                    break;
15095                case ProcessList.SCHED_GROUP_DEFAULT:
15096                    schedGroup = 'F';
15097                    break;
15098                case ProcessList.SCHED_GROUP_TOP_APP:
15099                    schedGroup = 'T';
15100                    break;
15101                default:
15102                    schedGroup = '?';
15103                    break;
15104            }
15105            char foreground;
15106            if (r.foregroundActivities) {
15107                foreground = 'A';
15108            } else if (r.foregroundServices) {
15109                foreground = 'S';
15110            } else {
15111                foreground = ' ';
15112            }
15113            String procState = ProcessList.makeProcStateString(r.curProcState);
15114            pw.print(prefix);
15115            pw.print(r.persistent ? persistentLabel : normalLabel);
15116            pw.print(" #");
15117            int num = (origList.size()-1)-list.get(i).second;
15118            if (num < 10) pw.print(' ');
15119            pw.print(num);
15120            pw.print(": ");
15121            pw.print(oomAdj);
15122            pw.print(' ');
15123            pw.print(schedGroup);
15124            pw.print('/');
15125            pw.print(foreground);
15126            pw.print('/');
15127            pw.print(procState);
15128            pw.print(" trm:");
15129            if (r.trimMemoryLevel < 10) pw.print(' ');
15130            pw.print(r.trimMemoryLevel);
15131            pw.print(' ');
15132            pw.print(r.toShortString());
15133            pw.print(" (");
15134            pw.print(r.adjType);
15135            pw.println(')');
15136            if (r.adjSource != null || r.adjTarget != null) {
15137                pw.print(prefix);
15138                pw.print("    ");
15139                if (r.adjTarget instanceof ComponentName) {
15140                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15141                } else if (r.adjTarget != null) {
15142                    pw.print(r.adjTarget.toString());
15143                } else {
15144                    pw.print("{null}");
15145                }
15146                pw.print("<=");
15147                if (r.adjSource instanceof ProcessRecord) {
15148                    pw.print("Proc{");
15149                    pw.print(((ProcessRecord)r.adjSource).toShortString());
15150                    pw.println("}");
15151                } else if (r.adjSource != null) {
15152                    pw.println(r.adjSource.toString());
15153                } else {
15154                    pw.println("{null}");
15155                }
15156            }
15157            if (inclDetails) {
15158                pw.print(prefix);
15159                pw.print("    ");
15160                pw.print("oom: max="); pw.print(r.maxAdj);
15161                pw.print(" curRaw="); pw.print(r.curRawAdj);
15162                pw.print(" setRaw="); pw.print(r.setRawAdj);
15163                pw.print(" cur="); pw.print(r.curAdj);
15164                pw.print(" set="); pw.println(r.setAdj);
15165                pw.print(prefix);
15166                pw.print("    ");
15167                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15168                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15169                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15170                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15171                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15172                pw.println();
15173                pw.print(prefix);
15174                pw.print("    ");
15175                pw.print("cached="); pw.print(r.cached);
15176                pw.print(" empty="); pw.print(r.empty);
15177                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15178
15179                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15180                    if (r.lastWakeTime != 0) {
15181                        long wtime;
15182                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15183                        synchronized (stats) {
15184                            wtime = stats.getProcessWakeTime(r.info.uid,
15185                                    r.pid, curRealtime);
15186                        }
15187                        long timeUsed = wtime - r.lastWakeTime;
15188                        pw.print(prefix);
15189                        pw.print("    ");
15190                        pw.print("keep awake over ");
15191                        TimeUtils.formatDuration(realtimeSince, pw);
15192                        pw.print(" used ");
15193                        TimeUtils.formatDuration(timeUsed, pw);
15194                        pw.print(" (");
15195                        pw.print((timeUsed*100)/realtimeSince);
15196                        pw.println("%)");
15197                    }
15198                    if (r.lastCpuTime != 0) {
15199                        long timeUsed = r.curCpuTime - r.lastCpuTime;
15200                        pw.print(prefix);
15201                        pw.print("    ");
15202                        pw.print("run cpu over ");
15203                        TimeUtils.formatDuration(uptimeSince, pw);
15204                        pw.print(" used ");
15205                        TimeUtils.formatDuration(timeUsed, pw);
15206                        pw.print(" (");
15207                        pw.print((timeUsed*100)/uptimeSince);
15208                        pw.println("%)");
15209                    }
15210                }
15211            }
15212        }
15213        return true;
15214    }
15215
15216    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15217            String[] args) {
15218        ArrayList<ProcessRecord> procs;
15219        synchronized (this) {
15220            if (args != null && args.length > start
15221                    && args[start].charAt(0) != '-') {
15222                procs = new ArrayList<ProcessRecord>();
15223                int pid = -1;
15224                try {
15225                    pid = Integer.parseInt(args[start]);
15226                } catch (NumberFormatException e) {
15227                }
15228                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15229                    ProcessRecord proc = mLruProcesses.get(i);
15230                    if (proc.pid == pid) {
15231                        procs.add(proc);
15232                    } else if (allPkgs && proc.pkgList != null
15233                            && proc.pkgList.containsKey(args[start])) {
15234                        procs.add(proc);
15235                    } else if (proc.processName.equals(args[start])) {
15236                        procs.add(proc);
15237                    }
15238                }
15239                if (procs.size() <= 0) {
15240                    return null;
15241                }
15242            } else {
15243                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15244            }
15245        }
15246        return procs;
15247    }
15248
15249    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15250            PrintWriter pw, String[] args) {
15251        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15252        if (procs == null) {
15253            pw.println("No process found for: " + args[0]);
15254            return;
15255        }
15256
15257        long uptime = SystemClock.uptimeMillis();
15258        long realtime = SystemClock.elapsedRealtime();
15259        pw.println("Applications Graphics Acceleration Info:");
15260        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15261
15262        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15263            ProcessRecord r = procs.get(i);
15264            if (r.thread != null) {
15265                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15266                pw.flush();
15267                try {
15268                    TransferPipe tp = new TransferPipe();
15269                    try {
15270                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15271                        tp.go(fd);
15272                    } finally {
15273                        tp.kill();
15274                    }
15275                } catch (IOException e) {
15276                    pw.println("Failure while dumping the app: " + r);
15277                    pw.flush();
15278                } catch (RemoteException e) {
15279                    pw.println("Got a RemoteException while dumping the app " + r);
15280                    pw.flush();
15281                }
15282            }
15283        }
15284    }
15285
15286    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15287        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15288        if (procs == null) {
15289            pw.println("No process found for: " + args[0]);
15290            return;
15291        }
15292
15293        pw.println("Applications Database Info:");
15294
15295        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15296            ProcessRecord r = procs.get(i);
15297            if (r.thread != null) {
15298                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15299                pw.flush();
15300                try {
15301                    TransferPipe tp = new TransferPipe();
15302                    try {
15303                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15304                        tp.go(fd);
15305                    } finally {
15306                        tp.kill();
15307                    }
15308                } catch (IOException e) {
15309                    pw.println("Failure while dumping the app: " + r);
15310                    pw.flush();
15311                } catch (RemoteException e) {
15312                    pw.println("Got a RemoteException while dumping the app " + r);
15313                    pw.flush();
15314                }
15315            }
15316        }
15317    }
15318
15319    final static class MemItem {
15320        final boolean isProc;
15321        final String label;
15322        final String shortLabel;
15323        final long pss;
15324        final long swapPss;
15325        final int id;
15326        final boolean hasActivities;
15327        ArrayList<MemItem> subitems;
15328
15329        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15330                boolean _hasActivities) {
15331            isProc = true;
15332            label = _label;
15333            shortLabel = _shortLabel;
15334            pss = _pss;
15335            swapPss = _swapPss;
15336            id = _id;
15337            hasActivities = _hasActivities;
15338        }
15339
15340        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15341            isProc = false;
15342            label = _label;
15343            shortLabel = _shortLabel;
15344            pss = _pss;
15345            swapPss = _swapPss;
15346            id = _id;
15347            hasActivities = false;
15348        }
15349    }
15350
15351    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15352            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15353        if (sort && !isCompact) {
15354            Collections.sort(items, new Comparator<MemItem>() {
15355                @Override
15356                public int compare(MemItem lhs, MemItem rhs) {
15357                    if (lhs.pss < rhs.pss) {
15358                        return 1;
15359                    } else if (lhs.pss > rhs.pss) {
15360                        return -1;
15361                    }
15362                    return 0;
15363                }
15364            });
15365        }
15366
15367        for (int i=0; i<items.size(); i++) {
15368            MemItem mi = items.get(i);
15369            if (!isCompact) {
15370                if (dumpSwapPss) {
15371                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15372                            mi.label, stringifyKBSize(mi.swapPss));
15373                } else {
15374                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15375                }
15376            } else if (mi.isProc) {
15377                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15378                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15379                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15380                pw.println(mi.hasActivities ? ",a" : ",e");
15381            } else {
15382                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15383                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15384            }
15385            if (mi.subitems != null) {
15386                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15387                        true, isCompact, dumpSwapPss);
15388            }
15389        }
15390    }
15391
15392    // These are in KB.
15393    static final long[] DUMP_MEM_BUCKETS = new long[] {
15394        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15395        120*1024, 160*1024, 200*1024,
15396        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15397        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15398    };
15399
15400    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15401            boolean stackLike) {
15402        int start = label.lastIndexOf('.');
15403        if (start >= 0) start++;
15404        else start = 0;
15405        int end = label.length();
15406        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15407            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15408                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15409                out.append(bucket);
15410                out.append(stackLike ? "MB." : "MB ");
15411                out.append(label, start, end);
15412                return;
15413            }
15414        }
15415        out.append(memKB/1024);
15416        out.append(stackLike ? "MB." : "MB ");
15417        out.append(label, start, end);
15418    }
15419
15420    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15421            ProcessList.NATIVE_ADJ,
15422            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15423            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15424            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15425            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15426            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15427            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
15428    };
15429    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15430            "Native",
15431            "System", "Persistent", "Persistent Service", "Foreground",
15432            "Visible", "Perceptible",
15433            "Heavy Weight", "Backup",
15434            "A Services", "Home",
15435            "Previous", "B Services", "Cached"
15436    };
15437    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15438            "native",
15439            "sys", "pers", "persvc", "fore",
15440            "vis", "percept",
15441            "heavy", "backup",
15442            "servicea", "home",
15443            "prev", "serviceb", "cached"
15444    };
15445
15446    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15447            long realtime, boolean isCheckinRequest, boolean isCompact) {
15448        if (isCompact) {
15449            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15450        }
15451        if (isCheckinRequest || isCompact) {
15452            // short checkin version
15453            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15454        } else {
15455            pw.println("Applications Memory Usage (in Kilobytes):");
15456            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15457        }
15458    }
15459
15460    private static final int KSM_SHARED = 0;
15461    private static final int KSM_SHARING = 1;
15462    private static final int KSM_UNSHARED = 2;
15463    private static final int KSM_VOLATILE = 3;
15464
15465    private final long[] getKsmInfo() {
15466        long[] longOut = new long[4];
15467        final int[] SINGLE_LONG_FORMAT = new int[] {
15468            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15469        };
15470        long[] longTmp = new long[1];
15471        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15472                SINGLE_LONG_FORMAT, null, longTmp, null);
15473        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15474        longTmp[0] = 0;
15475        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15476                SINGLE_LONG_FORMAT, null, longTmp, null);
15477        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15478        longTmp[0] = 0;
15479        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15480                SINGLE_LONG_FORMAT, null, longTmp, null);
15481        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15482        longTmp[0] = 0;
15483        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15484                SINGLE_LONG_FORMAT, null, longTmp, null);
15485        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15486        return longOut;
15487    }
15488
15489    private static String stringifySize(long size, int order) {
15490        Locale locale = Locale.US;
15491        switch (order) {
15492            case 1:
15493                return String.format(locale, "%,13d", size);
15494            case 1024:
15495                return String.format(locale, "%,9dK", size / 1024);
15496            case 1024 * 1024:
15497                return String.format(locale, "%,5dM", size / 1024 / 1024);
15498            case 1024 * 1024 * 1024:
15499                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15500            default:
15501                throw new IllegalArgumentException("Invalid size order");
15502        }
15503    }
15504
15505    private static String stringifyKBSize(long size) {
15506        return stringifySize(size * 1024, 1024);
15507    }
15508
15509    // Update this version number in case you change the 'compact' format
15510    private static final int MEMINFO_COMPACT_VERSION = 1;
15511
15512    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15513            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15514        boolean dumpDetails = false;
15515        boolean dumpFullDetails = false;
15516        boolean dumpDalvik = false;
15517        boolean dumpSummaryOnly = false;
15518        boolean dumpUnreachable = false;
15519        boolean oomOnly = false;
15520        boolean isCompact = false;
15521        boolean localOnly = false;
15522        boolean packages = false;
15523        boolean isCheckinRequest = false;
15524        boolean dumpSwapPss = false;
15525
15526        int opti = 0;
15527        while (opti < args.length) {
15528            String opt = args[opti];
15529            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15530                break;
15531            }
15532            opti++;
15533            if ("-a".equals(opt)) {
15534                dumpDetails = true;
15535                dumpFullDetails = true;
15536                dumpDalvik = true;
15537                dumpSwapPss = true;
15538            } else if ("-d".equals(opt)) {
15539                dumpDalvik = true;
15540            } else if ("-c".equals(opt)) {
15541                isCompact = true;
15542            } else if ("-s".equals(opt)) {
15543                dumpDetails = true;
15544                dumpSummaryOnly = true;
15545            } else if ("-S".equals(opt)) {
15546                dumpSwapPss = true;
15547            } else if ("--unreachable".equals(opt)) {
15548                dumpUnreachable = true;
15549            } else if ("--oom".equals(opt)) {
15550                oomOnly = true;
15551            } else if ("--local".equals(opt)) {
15552                localOnly = true;
15553            } else if ("--package".equals(opt)) {
15554                packages = true;
15555            } else if ("--checkin".equals(opt)) {
15556                isCheckinRequest = true;
15557
15558            } else if ("-h".equals(opt)) {
15559                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15560                pw.println("  -a: include all available information for each process.");
15561                pw.println("  -d: include dalvik details.");
15562                pw.println("  -c: dump in a compact machine-parseable representation.");
15563                pw.println("  -s: dump only summary of application memory usage.");
15564                pw.println("  -S: dump also SwapPss.");
15565                pw.println("  --oom: only show processes organized by oom adj.");
15566                pw.println("  --local: only collect details locally, don't call process.");
15567                pw.println("  --package: interpret process arg as package, dumping all");
15568                pw.println("             processes that have loaded that package.");
15569                pw.println("  --checkin: dump data for a checkin");
15570                pw.println("If [process] is specified it can be the name or ");
15571                pw.println("pid of a specific process to dump.");
15572                return;
15573            } else {
15574                pw.println("Unknown argument: " + opt + "; use -h for help");
15575            }
15576        }
15577
15578        long uptime = SystemClock.uptimeMillis();
15579        long realtime = SystemClock.elapsedRealtime();
15580        final long[] tmpLong = new long[1];
15581
15582        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15583        if (procs == null) {
15584            // No Java processes.  Maybe they want to print a native process.
15585            if (args != null && args.length > opti
15586                    && args[opti].charAt(0) != '-') {
15587                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15588                        = new ArrayList<ProcessCpuTracker.Stats>();
15589                updateCpuStatsNow();
15590                int findPid = -1;
15591                try {
15592                    findPid = Integer.parseInt(args[opti]);
15593                } catch (NumberFormatException e) {
15594                }
15595                synchronized (mProcessCpuTracker) {
15596                    final int N = mProcessCpuTracker.countStats();
15597                    for (int i=0; i<N; i++) {
15598                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15599                        if (st.pid == findPid || (st.baseName != null
15600                                && st.baseName.equals(args[opti]))) {
15601                            nativeProcs.add(st);
15602                        }
15603                    }
15604                }
15605                if (nativeProcs.size() > 0) {
15606                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15607                            isCompact);
15608                    Debug.MemoryInfo mi = null;
15609                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15610                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15611                        final int pid = r.pid;
15612                        if (!isCheckinRequest && dumpDetails) {
15613                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15614                        }
15615                        if (mi == null) {
15616                            mi = new Debug.MemoryInfo();
15617                        }
15618                        if (dumpDetails || (!brief && !oomOnly)) {
15619                            Debug.getMemoryInfo(pid, mi);
15620                        } else {
15621                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15622                            mi.dalvikPrivateDirty = (int)tmpLong[0];
15623                        }
15624                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15625                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15626                        if (isCheckinRequest) {
15627                            pw.println();
15628                        }
15629                    }
15630                    return;
15631                }
15632            }
15633            pw.println("No process found for: " + args[opti]);
15634            return;
15635        }
15636
15637        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15638            dumpDetails = true;
15639        }
15640
15641        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15642
15643        String[] innerArgs = new String[args.length-opti];
15644        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15645
15646        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15647        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15648        long nativePss = 0;
15649        long nativeSwapPss = 0;
15650        long dalvikPss = 0;
15651        long dalvikSwapPss = 0;
15652        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15653                EmptyArray.LONG;
15654        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15655                EmptyArray.LONG;
15656        long otherPss = 0;
15657        long otherSwapPss = 0;
15658        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15659        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15660
15661        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15662        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15663        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15664                new ArrayList[DUMP_MEM_OOM_LABEL.length];
15665
15666        long totalPss = 0;
15667        long totalSwapPss = 0;
15668        long cachedPss = 0;
15669        long cachedSwapPss = 0;
15670        boolean hasSwapPss = false;
15671
15672        Debug.MemoryInfo mi = null;
15673        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15674            final ProcessRecord r = procs.get(i);
15675            final IApplicationThread thread;
15676            final int pid;
15677            final int oomAdj;
15678            final boolean hasActivities;
15679            synchronized (this) {
15680                thread = r.thread;
15681                pid = r.pid;
15682                oomAdj = r.getSetAdjWithServices();
15683                hasActivities = r.activities.size() > 0;
15684            }
15685            if (thread != null) {
15686                if (!isCheckinRequest && dumpDetails) {
15687                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15688                }
15689                if (mi == null) {
15690                    mi = new Debug.MemoryInfo();
15691                }
15692                if (dumpDetails || (!brief && !oomOnly)) {
15693                    Debug.getMemoryInfo(pid, mi);
15694                    hasSwapPss = mi.hasSwappedOutPss;
15695                } else {
15696                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15697                    mi.dalvikPrivateDirty = (int)tmpLong[0];
15698                }
15699                if (dumpDetails) {
15700                    if (localOnly) {
15701                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15702                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15703                        if (isCheckinRequest) {
15704                            pw.println();
15705                        }
15706                    } else {
15707                        try {
15708                            pw.flush();
15709                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15710                                    dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
15711                        } catch (RemoteException e) {
15712                            if (!isCheckinRequest) {
15713                                pw.println("Got RemoteException!");
15714                                pw.flush();
15715                            }
15716                        }
15717                    }
15718                }
15719
15720                final long myTotalPss = mi.getTotalPss();
15721                final long myTotalUss = mi.getTotalUss();
15722                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15723
15724                synchronized (this) {
15725                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15726                        // Record this for posterity if the process has been stable.
15727                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
15728                    }
15729                }
15730
15731                if (!isCheckinRequest && mi != null) {
15732                    totalPss += myTotalPss;
15733                    totalSwapPss += myTotalSwapPss;
15734                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
15735                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
15736                            myTotalSwapPss, pid, hasActivities);
15737                    procMems.add(pssItem);
15738                    procMemsMap.put(pid, pssItem);
15739
15740                    nativePss += mi.nativePss;
15741                    nativeSwapPss += mi.nativeSwappedOutPss;
15742                    dalvikPss += mi.dalvikPss;
15743                    dalvikSwapPss += mi.dalvikSwappedOutPss;
15744                    for (int j=0; j<dalvikSubitemPss.length; j++) {
15745                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15746                        dalvikSubitemSwapPss[j] +=
15747                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15748                    }
15749                    otherPss += mi.otherPss;
15750                    otherSwapPss += mi.otherSwappedOutPss;
15751                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15752                        long mem = mi.getOtherPss(j);
15753                        miscPss[j] += mem;
15754                        otherPss -= mem;
15755                        mem = mi.getOtherSwappedOutPss(j);
15756                        miscSwapPss[j] += mem;
15757                        otherSwapPss -= mem;
15758                    }
15759
15760                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15761                        cachedPss += myTotalPss;
15762                        cachedSwapPss += myTotalSwapPss;
15763                    }
15764
15765                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
15766                        if (oomIndex == (oomPss.length - 1)
15767                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
15768                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
15769                            oomPss[oomIndex] += myTotalPss;
15770                            oomSwapPss[oomIndex] += myTotalSwapPss;
15771                            if (oomProcs[oomIndex] == null) {
15772                                oomProcs[oomIndex] = new ArrayList<MemItem>();
15773                            }
15774                            oomProcs[oomIndex].add(pssItem);
15775                            break;
15776                        }
15777                    }
15778                }
15779            }
15780        }
15781
15782        long nativeProcTotalPss = 0;
15783
15784        if (!isCheckinRequest && procs.size() > 1 && !packages) {
15785            // If we are showing aggregations, also look for native processes to
15786            // include so that our aggregations are more accurate.
15787            updateCpuStatsNow();
15788            mi = null;
15789            synchronized (mProcessCpuTracker) {
15790                final int N = mProcessCpuTracker.countStats();
15791                for (int i=0; i<N; i++) {
15792                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15793                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
15794                        if (mi == null) {
15795                            mi = new Debug.MemoryInfo();
15796                        }
15797                        if (!brief && !oomOnly) {
15798                            Debug.getMemoryInfo(st.pid, mi);
15799                        } else {
15800                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
15801                            mi.nativePrivateDirty = (int)tmpLong[0];
15802                        }
15803
15804                        final long myTotalPss = mi.getTotalPss();
15805                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15806                        totalPss += myTotalPss;
15807                        nativeProcTotalPss += myTotalPss;
15808
15809                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
15810                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
15811                        procMems.add(pssItem);
15812
15813                        nativePss += mi.nativePss;
15814                        nativeSwapPss += mi.nativeSwappedOutPss;
15815                        dalvikPss += mi.dalvikPss;
15816                        dalvikSwapPss += mi.dalvikSwappedOutPss;
15817                        for (int j=0; j<dalvikSubitemPss.length; j++) {
15818                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15819                            dalvikSubitemSwapPss[j] +=
15820                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15821                        }
15822                        otherPss += mi.otherPss;
15823                        otherSwapPss += mi.otherSwappedOutPss;
15824                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15825                            long mem = mi.getOtherPss(j);
15826                            miscPss[j] += mem;
15827                            otherPss -= mem;
15828                            mem = mi.getOtherSwappedOutPss(j);
15829                            miscSwapPss[j] += mem;
15830                            otherSwapPss -= mem;
15831                        }
15832                        oomPss[0] += myTotalPss;
15833                        oomSwapPss[0] += myTotalSwapPss;
15834                        if (oomProcs[0] == null) {
15835                            oomProcs[0] = new ArrayList<MemItem>();
15836                        }
15837                        oomProcs[0].add(pssItem);
15838                    }
15839                }
15840            }
15841
15842            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
15843
15844            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
15845            final MemItem dalvikItem =
15846                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
15847            if (dalvikSubitemPss.length > 0) {
15848                dalvikItem.subitems = new ArrayList<MemItem>();
15849                for (int j=0; j<dalvikSubitemPss.length; j++) {
15850                    final String name = Debug.MemoryInfo.getOtherLabel(
15851                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
15852                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
15853                                    dalvikSubitemSwapPss[j], j));
15854                }
15855            }
15856            catMems.add(dalvikItem);
15857            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
15858            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15859                String label = Debug.MemoryInfo.getOtherLabel(j);
15860                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
15861            }
15862
15863            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
15864            for (int j=0; j<oomPss.length; j++) {
15865                if (oomPss[j] != 0) {
15866                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
15867                            : DUMP_MEM_OOM_LABEL[j];
15868                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
15869                            DUMP_MEM_OOM_ADJ[j]);
15870                    item.subitems = oomProcs[j];
15871                    oomMems.add(item);
15872                }
15873            }
15874
15875            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
15876            if (!brief && !oomOnly && !isCompact) {
15877                pw.println();
15878                pw.println("Total PSS by process:");
15879                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
15880                pw.println();
15881            }
15882            if (!isCompact) {
15883                pw.println("Total PSS by OOM adjustment:");
15884            }
15885            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
15886            if (!brief && !oomOnly) {
15887                PrintWriter out = categoryPw != null ? categoryPw : pw;
15888                if (!isCompact) {
15889                    out.println();
15890                    out.println("Total PSS by category:");
15891                }
15892                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
15893            }
15894            if (!isCompact) {
15895                pw.println();
15896            }
15897            MemInfoReader memInfo = new MemInfoReader();
15898            memInfo.readMemInfo();
15899            if (nativeProcTotalPss > 0) {
15900                synchronized (this) {
15901                    final long cachedKb = memInfo.getCachedSizeKb();
15902                    final long freeKb = memInfo.getFreeSizeKb();
15903                    final long zramKb = memInfo.getZramTotalSizeKb();
15904                    final long kernelKb = memInfo.getKernelUsedSizeKb();
15905                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
15906                            kernelKb*1024, nativeProcTotalPss*1024);
15907                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
15908                            nativeProcTotalPss);
15909                }
15910            }
15911            if (!brief) {
15912                if (!isCompact) {
15913                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
15914                    pw.print(" (status ");
15915                    switch (mLastMemoryLevel) {
15916                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
15917                            pw.println("normal)");
15918                            break;
15919                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
15920                            pw.println("moderate)");
15921                            break;
15922                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
15923                            pw.println("low)");
15924                            break;
15925                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15926                            pw.println("critical)");
15927                            break;
15928                        default:
15929                            pw.print(mLastMemoryLevel);
15930                            pw.println(")");
15931                            break;
15932                    }
15933                    pw.print(" Free RAM: ");
15934                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15935                            + memInfo.getFreeSizeKb()));
15936                    pw.print(" (");
15937                    pw.print(stringifyKBSize(cachedPss));
15938                    pw.print(" cached pss + ");
15939                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
15940                    pw.print(" cached kernel + ");
15941                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
15942                    pw.println(" free)");
15943                } else {
15944                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
15945                    pw.print(cachedPss + memInfo.getCachedSizeKb()
15946                            + memInfo.getFreeSizeKb()); pw.print(",");
15947                    pw.println(totalPss - cachedPss);
15948                }
15949            }
15950            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
15951                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15952                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
15953            if (!isCompact) {
15954                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
15955                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
15956                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
15957                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
15958                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
15959            } else {
15960                pw.print("lostram,"); pw.println(lostRAM);
15961            }
15962            if (!brief) {
15963                if (memInfo.getZramTotalSizeKb() != 0) {
15964                    if (!isCompact) {
15965                        pw.print("     ZRAM: ");
15966                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
15967                                pw.print(" physical used for ");
15968                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
15969                                        - memInfo.getSwapFreeSizeKb()));
15970                                pw.print(" in swap (");
15971                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
15972                                pw.println(" total swap)");
15973                    } else {
15974                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
15975                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
15976                                pw.println(memInfo.getSwapFreeSizeKb());
15977                    }
15978                }
15979                final long[] ksm = getKsmInfo();
15980                if (!isCompact) {
15981                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15982                            || ksm[KSM_VOLATILE] != 0) {
15983                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
15984                                pw.print(" saved from shared ");
15985                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
15986                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
15987                                pw.print(" unshared; ");
15988                                pw.print(stringifyKBSize(
15989                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
15990                    }
15991                    pw.print("   Tuning: ");
15992                    pw.print(ActivityManager.staticGetMemoryClass());
15993                    pw.print(" (large ");
15994                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15995                    pw.print("), oom ");
15996                    pw.print(stringifySize(
15997                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
15998                    pw.print(", restore limit ");
15999                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
16000                    if (ActivityManager.isLowRamDeviceStatic()) {
16001                        pw.print(" (low-ram)");
16002                    }
16003                    if (ActivityManager.isHighEndGfx()) {
16004                        pw.print(" (high-end-gfx)");
16005                    }
16006                    pw.println();
16007                } else {
16008                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16009                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16010                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16011                    pw.print("tuning,");
16012                    pw.print(ActivityManager.staticGetMemoryClass());
16013                    pw.print(',');
16014                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16015                    pw.print(',');
16016                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16017                    if (ActivityManager.isLowRamDeviceStatic()) {
16018                        pw.print(",low-ram");
16019                    }
16020                    if (ActivityManager.isHighEndGfx()) {
16021                        pw.print(",high-end-gfx");
16022                    }
16023                    pw.println();
16024                }
16025            }
16026        }
16027    }
16028
16029    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16030            long memtrack, String name) {
16031        sb.append("  ");
16032        sb.append(ProcessList.makeOomAdjString(oomAdj));
16033        sb.append(' ');
16034        sb.append(ProcessList.makeProcStateString(procState));
16035        sb.append(' ');
16036        ProcessList.appendRamKb(sb, pss);
16037        sb.append(": ");
16038        sb.append(name);
16039        if (memtrack > 0) {
16040            sb.append(" (");
16041            sb.append(stringifyKBSize(memtrack));
16042            sb.append(" memtrack)");
16043        }
16044    }
16045
16046    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16047        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16048        sb.append(" (pid ");
16049        sb.append(mi.pid);
16050        sb.append(") ");
16051        sb.append(mi.adjType);
16052        sb.append('\n');
16053        if (mi.adjReason != null) {
16054            sb.append("                      ");
16055            sb.append(mi.adjReason);
16056            sb.append('\n');
16057        }
16058    }
16059
16060    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16061        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16062        for (int i=0, N=memInfos.size(); i<N; i++) {
16063            ProcessMemInfo mi = memInfos.get(i);
16064            infoMap.put(mi.pid, mi);
16065        }
16066        updateCpuStatsNow();
16067        long[] memtrackTmp = new long[1];
16068        synchronized (mProcessCpuTracker) {
16069            final int N = mProcessCpuTracker.countStats();
16070            for (int i=0; i<N; i++) {
16071                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16072                if (st.vsize > 0) {
16073                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
16074                    if (pss > 0) {
16075                        if (infoMap.indexOfKey(st.pid) < 0) {
16076                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16077                                    ProcessList.NATIVE_ADJ, -1, "native", null);
16078                            mi.pss = pss;
16079                            mi.memtrack = memtrackTmp[0];
16080                            memInfos.add(mi);
16081                        }
16082                    }
16083                }
16084            }
16085        }
16086
16087        long totalPss = 0;
16088        long totalMemtrack = 0;
16089        for (int i=0, N=memInfos.size(); i<N; i++) {
16090            ProcessMemInfo mi = memInfos.get(i);
16091            if (mi.pss == 0) {
16092                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16093                mi.memtrack = memtrackTmp[0];
16094            }
16095            totalPss += mi.pss;
16096            totalMemtrack += mi.memtrack;
16097        }
16098        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16099            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16100                if (lhs.oomAdj != rhs.oomAdj) {
16101                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16102                }
16103                if (lhs.pss != rhs.pss) {
16104                    return lhs.pss < rhs.pss ? 1 : -1;
16105                }
16106                return 0;
16107            }
16108        });
16109
16110        StringBuilder tag = new StringBuilder(128);
16111        StringBuilder stack = new StringBuilder(128);
16112        tag.append("Low on memory -- ");
16113        appendMemBucket(tag, totalPss, "total", false);
16114        appendMemBucket(stack, totalPss, "total", true);
16115
16116        StringBuilder fullNativeBuilder = new StringBuilder(1024);
16117        StringBuilder shortNativeBuilder = new StringBuilder(1024);
16118        StringBuilder fullJavaBuilder = new StringBuilder(1024);
16119
16120        boolean firstLine = true;
16121        int lastOomAdj = Integer.MIN_VALUE;
16122        long extraNativeRam = 0;
16123        long extraNativeMemtrack = 0;
16124        long cachedPss = 0;
16125        for (int i=0, N=memInfos.size(); i<N; i++) {
16126            ProcessMemInfo mi = memInfos.get(i);
16127
16128            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16129                cachedPss += mi.pss;
16130            }
16131
16132            if (mi.oomAdj != ProcessList.NATIVE_ADJ
16133                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
16134                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
16135                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16136                if (lastOomAdj != mi.oomAdj) {
16137                    lastOomAdj = mi.oomAdj;
16138                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16139                        tag.append(" / ");
16140                    }
16141                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16142                        if (firstLine) {
16143                            stack.append(":");
16144                            firstLine = false;
16145                        }
16146                        stack.append("\n\t at ");
16147                    } else {
16148                        stack.append("$");
16149                    }
16150                } else {
16151                    tag.append(" ");
16152                    stack.append("$");
16153                }
16154                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16155                    appendMemBucket(tag, mi.pss, mi.name, false);
16156                }
16157                appendMemBucket(stack, mi.pss, mi.name, true);
16158                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16159                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16160                    stack.append("(");
16161                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16162                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16163                            stack.append(DUMP_MEM_OOM_LABEL[k]);
16164                            stack.append(":");
16165                            stack.append(DUMP_MEM_OOM_ADJ[k]);
16166                        }
16167                    }
16168                    stack.append(")");
16169                }
16170            }
16171
16172            appendMemInfo(fullNativeBuilder, mi);
16173            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16174                // The short form only has native processes that are >= 512K.
16175                if (mi.pss >= 512) {
16176                    appendMemInfo(shortNativeBuilder, mi);
16177                } else {
16178                    extraNativeRam += mi.pss;
16179                    extraNativeMemtrack += mi.memtrack;
16180                }
16181            } else {
16182                // Short form has all other details, but if we have collected RAM
16183                // from smaller native processes let's dump a summary of that.
16184                if (extraNativeRam > 0) {
16185                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16186                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16187                    shortNativeBuilder.append('\n');
16188                    extraNativeRam = 0;
16189                }
16190                appendMemInfo(fullJavaBuilder, mi);
16191            }
16192        }
16193
16194        fullJavaBuilder.append("           ");
16195        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16196        fullJavaBuilder.append(": TOTAL");
16197        if (totalMemtrack > 0) {
16198            fullJavaBuilder.append(" (");
16199            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16200            fullJavaBuilder.append(" memtrack)");
16201        } else {
16202        }
16203        fullJavaBuilder.append("\n");
16204
16205        MemInfoReader memInfo = new MemInfoReader();
16206        memInfo.readMemInfo();
16207        final long[] infos = memInfo.getRawInfo();
16208
16209        StringBuilder memInfoBuilder = new StringBuilder(1024);
16210        Debug.getMemInfo(infos);
16211        memInfoBuilder.append("  MemInfo: ");
16212        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16213        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16214        memInfoBuilder.append(stringifyKBSize(
16215                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16216        memInfoBuilder.append(stringifyKBSize(
16217                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16218        memInfoBuilder.append(stringifyKBSize(
16219                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16220        memInfoBuilder.append("           ");
16221        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16222        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16223        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16224        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16225        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16226            memInfoBuilder.append("  ZRAM: ");
16227            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16228            memInfoBuilder.append(" RAM, ");
16229            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16230            memInfoBuilder.append(" swap total, ");
16231            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16232            memInfoBuilder.append(" swap free\n");
16233        }
16234        final long[] ksm = getKsmInfo();
16235        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16236                || ksm[KSM_VOLATILE] != 0) {
16237            memInfoBuilder.append("  KSM: ");
16238            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16239            memInfoBuilder.append(" saved from shared ");
16240            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16241            memInfoBuilder.append("\n       ");
16242            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16243            memInfoBuilder.append(" unshared; ");
16244            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16245            memInfoBuilder.append(" volatile\n");
16246        }
16247        memInfoBuilder.append("  Free RAM: ");
16248        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16249                + memInfo.getFreeSizeKb()));
16250        memInfoBuilder.append("\n");
16251        memInfoBuilder.append("  Used RAM: ");
16252        memInfoBuilder.append(stringifyKBSize(
16253                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16254        memInfoBuilder.append("\n");
16255        memInfoBuilder.append("  Lost RAM: ");
16256        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16257                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16258                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16259        memInfoBuilder.append("\n");
16260        Slog.i(TAG, "Low on memory:");
16261        Slog.i(TAG, shortNativeBuilder.toString());
16262        Slog.i(TAG, fullJavaBuilder.toString());
16263        Slog.i(TAG, memInfoBuilder.toString());
16264
16265        StringBuilder dropBuilder = new StringBuilder(1024);
16266        /*
16267        StringWriter oomSw = new StringWriter();
16268        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16269        StringWriter catSw = new StringWriter();
16270        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16271        String[] emptyArgs = new String[] { };
16272        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16273        oomPw.flush();
16274        String oomString = oomSw.toString();
16275        */
16276        dropBuilder.append("Low on memory:");
16277        dropBuilder.append(stack);
16278        dropBuilder.append('\n');
16279        dropBuilder.append(fullNativeBuilder);
16280        dropBuilder.append(fullJavaBuilder);
16281        dropBuilder.append('\n');
16282        dropBuilder.append(memInfoBuilder);
16283        dropBuilder.append('\n');
16284        /*
16285        dropBuilder.append(oomString);
16286        dropBuilder.append('\n');
16287        */
16288        StringWriter catSw = new StringWriter();
16289        synchronized (ActivityManagerService.this) {
16290            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16291            String[] emptyArgs = new String[] { };
16292            catPw.println();
16293            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16294            catPw.println();
16295            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
16296                    false, null).dumpLocked();
16297            catPw.println();
16298            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16299            catPw.flush();
16300        }
16301        dropBuilder.append(catSw.toString());
16302        addErrorToDropBox("lowmem", null, "system_server", null,
16303                null, tag.toString(), dropBuilder.toString(), null, null);
16304        //Slog.i(TAG, "Sent to dropbox:");
16305        //Slog.i(TAG, dropBuilder.toString());
16306        synchronized (ActivityManagerService.this) {
16307            long now = SystemClock.uptimeMillis();
16308            if (mLastMemUsageReportTime < now) {
16309                mLastMemUsageReportTime = now;
16310            }
16311        }
16312    }
16313
16314    /**
16315     * Searches array of arguments for the specified string
16316     * @param args array of argument strings
16317     * @param value value to search for
16318     * @return true if the value is contained in the array
16319     */
16320    private static boolean scanArgs(String[] args, String value) {
16321        if (args != null) {
16322            for (String arg : args) {
16323                if (value.equals(arg)) {
16324                    return true;
16325                }
16326            }
16327        }
16328        return false;
16329    }
16330
16331    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16332            ContentProviderRecord cpr, boolean always) {
16333        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16334
16335        if (!inLaunching || always) {
16336            synchronized (cpr) {
16337                cpr.launchingApp = null;
16338                cpr.notifyAll();
16339            }
16340            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16341            String names[] = cpr.info.authority.split(";");
16342            for (int j = 0; j < names.length; j++) {
16343                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16344            }
16345        }
16346
16347        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16348            ContentProviderConnection conn = cpr.connections.get(i);
16349            if (conn.waiting) {
16350                // If this connection is waiting for the provider, then we don't
16351                // need to mess with its process unless we are always removing
16352                // or for some reason the provider is not currently launching.
16353                if (inLaunching && !always) {
16354                    continue;
16355                }
16356            }
16357            ProcessRecord capp = conn.client;
16358            conn.dead = true;
16359            if (conn.stableCount > 0) {
16360                if (!capp.persistent && capp.thread != null
16361                        && capp.pid != 0
16362                        && capp.pid != MY_PID) {
16363                    capp.kill("depends on provider "
16364                            + cpr.name.flattenToShortString()
16365                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
16366                }
16367            } else if (capp.thread != null && conn.provider.provider != null) {
16368                try {
16369                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16370                } catch (RemoteException e) {
16371                }
16372                // In the protocol here, we don't expect the client to correctly
16373                // clean up this connection, we'll just remove it.
16374                cpr.connections.remove(i);
16375                if (conn.client.conProviders.remove(conn)) {
16376                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16377                }
16378            }
16379        }
16380
16381        if (inLaunching && always) {
16382            mLaunchingProviders.remove(cpr);
16383        }
16384        return inLaunching;
16385    }
16386
16387    /**
16388     * Main code for cleaning up a process when it has gone away.  This is
16389     * called both as a result of the process dying, or directly when stopping
16390     * a process when running in single process mode.
16391     *
16392     * @return Returns true if the given process has been restarted, so the
16393     * app that was passed in must remain on the process lists.
16394     */
16395    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16396            boolean restarting, boolean allowRestart, int index) {
16397        if (index >= 0) {
16398            removeLruProcessLocked(app);
16399            ProcessList.remove(app.pid);
16400        }
16401
16402        mProcessesToGc.remove(app);
16403        mPendingPssProcesses.remove(app);
16404
16405        // Dismiss any open dialogs.
16406        if (app.crashDialog != null && !app.forceCrashReport) {
16407            app.crashDialog.dismiss();
16408            app.crashDialog = null;
16409        }
16410        if (app.anrDialog != null) {
16411            app.anrDialog.dismiss();
16412            app.anrDialog = null;
16413        }
16414        if (app.waitDialog != null) {
16415            app.waitDialog.dismiss();
16416            app.waitDialog = null;
16417        }
16418
16419        app.crashing = false;
16420        app.notResponding = false;
16421
16422        app.resetPackageList(mProcessStats);
16423        app.unlinkDeathRecipient();
16424        app.makeInactive(mProcessStats);
16425        app.waitingToKill = null;
16426        app.forcingToForeground = null;
16427        updateProcessForegroundLocked(app, false, false);
16428        app.foregroundActivities = false;
16429        app.hasShownUi = false;
16430        app.treatLikeActivity = false;
16431        app.hasAboveClient = false;
16432        app.hasClientActivities = false;
16433
16434        mServices.killServicesLocked(app, allowRestart);
16435
16436        boolean restart = false;
16437
16438        // Remove published content providers.
16439        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16440            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16441            final boolean always = app.bad || !allowRestart;
16442            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16443            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16444                // We left the provider in the launching list, need to
16445                // restart it.
16446                restart = true;
16447            }
16448
16449            cpr.provider = null;
16450            cpr.proc = null;
16451        }
16452        app.pubProviders.clear();
16453
16454        // Take care of any launching providers waiting for this process.
16455        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16456            restart = true;
16457        }
16458
16459        // Unregister from connected content providers.
16460        if (!app.conProviders.isEmpty()) {
16461            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16462                ContentProviderConnection conn = app.conProviders.get(i);
16463                conn.provider.connections.remove(conn);
16464                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16465                        conn.provider.name);
16466            }
16467            app.conProviders.clear();
16468        }
16469
16470        // At this point there may be remaining entries in mLaunchingProviders
16471        // where we were the only one waiting, so they are no longer of use.
16472        // Look for these and clean up if found.
16473        // XXX Commented out for now.  Trying to figure out a way to reproduce
16474        // the actual situation to identify what is actually going on.
16475        if (false) {
16476            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16477                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16478                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16479                    synchronized (cpr) {
16480                        cpr.launchingApp = null;
16481                        cpr.notifyAll();
16482                    }
16483                }
16484            }
16485        }
16486
16487        skipCurrentReceiverLocked(app);
16488
16489        // Unregister any receivers.
16490        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16491            removeReceiverLocked(app.receivers.valueAt(i));
16492        }
16493        app.receivers.clear();
16494
16495        // If the app is undergoing backup, tell the backup manager about it
16496        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16497            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16498                    + mBackupTarget.appInfo + " died during backup");
16499            try {
16500                IBackupManager bm = IBackupManager.Stub.asInterface(
16501                        ServiceManager.getService(Context.BACKUP_SERVICE));
16502                bm.agentDisconnected(app.info.packageName);
16503            } catch (RemoteException e) {
16504                // can't happen; backup manager is local
16505            }
16506        }
16507
16508        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16509            ProcessChangeItem item = mPendingProcessChanges.get(i);
16510            if (item.pid == app.pid) {
16511                mPendingProcessChanges.remove(i);
16512                mAvailProcessChanges.add(item);
16513            }
16514        }
16515        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16516                null).sendToTarget();
16517
16518        // If the caller is restarting this app, then leave it in its
16519        // current lists and let the caller take care of it.
16520        if (restarting) {
16521            return false;
16522        }
16523
16524        if (!app.persistent || app.isolated) {
16525            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16526                    "Removing non-persistent process during cleanup: " + app);
16527            removeProcessNameLocked(app.processName, app.uid);
16528            if (mHeavyWeightProcess == app) {
16529                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16530                        mHeavyWeightProcess.userId, 0));
16531                mHeavyWeightProcess = null;
16532            }
16533        } else if (!app.removed) {
16534            // This app is persistent, so we need to keep its record around.
16535            // If it is not already on the pending app list, add it there
16536            // and start a new process for it.
16537            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16538                mPersistentStartingProcesses.add(app);
16539                restart = true;
16540            }
16541        }
16542        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16543                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16544        mProcessesOnHold.remove(app);
16545
16546        if (app == mHomeProcess) {
16547            mHomeProcess = null;
16548        }
16549        if (app == mPreviousProcess) {
16550            mPreviousProcess = null;
16551        }
16552
16553        if (restart && !app.isolated) {
16554            // We have components that still need to be running in the
16555            // process, so re-launch it.
16556            if (index < 0) {
16557                ProcessList.remove(app.pid);
16558            }
16559            addProcessNameLocked(app);
16560            startProcessLocked(app, "restart", app.processName);
16561            return true;
16562        } else if (app.pid > 0 && app.pid != MY_PID) {
16563            // Goodbye!
16564            boolean removed;
16565            synchronized (mPidsSelfLocked) {
16566                mPidsSelfLocked.remove(app.pid);
16567                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16568            }
16569            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16570            if (app.isolated) {
16571                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16572            }
16573            app.setPid(0);
16574        }
16575        return false;
16576    }
16577
16578    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16579        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16580            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16581            if (cpr.launchingApp == app) {
16582                return true;
16583            }
16584        }
16585        return false;
16586    }
16587
16588    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16589        // Look through the content providers we are waiting to have launched,
16590        // and if any run in this process then either schedule a restart of
16591        // the process or kill the client waiting for it if this process has
16592        // gone bad.
16593        boolean restart = false;
16594        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16595            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16596            if (cpr.launchingApp == app) {
16597                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16598                    restart = true;
16599                } else {
16600                    removeDyingProviderLocked(app, cpr, true);
16601                }
16602            }
16603        }
16604        return restart;
16605    }
16606
16607    // =========================================================
16608    // SERVICES
16609    // =========================================================
16610
16611    @Override
16612    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16613            int flags) {
16614        enforceNotIsolatedCaller("getServices");
16615        synchronized (this) {
16616            return mServices.getRunningServiceInfoLocked(maxNum, flags);
16617        }
16618    }
16619
16620    @Override
16621    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16622        enforceNotIsolatedCaller("getRunningServiceControlPanel");
16623        synchronized (this) {
16624            return mServices.getRunningServiceControlPanelLocked(name);
16625        }
16626    }
16627
16628    @Override
16629    public ComponentName startService(IApplicationThread caller, Intent service,
16630            String resolvedType, String callingPackage, int userId)
16631            throws TransactionTooLargeException {
16632        enforceNotIsolatedCaller("startService");
16633        // Refuse possible leaked file descriptors
16634        if (service != null && service.hasFileDescriptors() == true) {
16635            throw new IllegalArgumentException("File descriptors passed in Intent");
16636        }
16637
16638        if (callingPackage == null) {
16639            throw new IllegalArgumentException("callingPackage cannot be null");
16640        }
16641
16642        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16643                "startService: " + service + " type=" + resolvedType);
16644        synchronized(this) {
16645            final int callingPid = Binder.getCallingPid();
16646            final int callingUid = Binder.getCallingUid();
16647            final long origId = Binder.clearCallingIdentity();
16648            ComponentName res = mServices.startServiceLocked(caller, service,
16649                    resolvedType, callingPid, callingUid, callingPackage, userId);
16650            Binder.restoreCallingIdentity(origId);
16651            return res;
16652        }
16653    }
16654
16655    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16656            String callingPackage, int userId)
16657            throws TransactionTooLargeException {
16658        synchronized(this) {
16659            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16660                    "startServiceInPackage: " + service + " type=" + resolvedType);
16661            final long origId = Binder.clearCallingIdentity();
16662            ComponentName res = mServices.startServiceLocked(null, service,
16663                    resolvedType, -1, uid, callingPackage, userId);
16664            Binder.restoreCallingIdentity(origId);
16665            return res;
16666        }
16667    }
16668
16669    @Override
16670    public int stopService(IApplicationThread caller, Intent service,
16671            String resolvedType, int userId) {
16672        enforceNotIsolatedCaller("stopService");
16673        // Refuse possible leaked file descriptors
16674        if (service != null && service.hasFileDescriptors() == true) {
16675            throw new IllegalArgumentException("File descriptors passed in Intent");
16676        }
16677
16678        synchronized(this) {
16679            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16680        }
16681    }
16682
16683    @Override
16684    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16685        enforceNotIsolatedCaller("peekService");
16686        // Refuse possible leaked file descriptors
16687        if (service != null && service.hasFileDescriptors() == true) {
16688            throw new IllegalArgumentException("File descriptors passed in Intent");
16689        }
16690
16691        if (callingPackage == null) {
16692            throw new IllegalArgumentException("callingPackage cannot be null");
16693        }
16694
16695        synchronized(this) {
16696            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16697        }
16698    }
16699
16700    @Override
16701    public boolean stopServiceToken(ComponentName className, IBinder token,
16702            int startId) {
16703        synchronized(this) {
16704            return mServices.stopServiceTokenLocked(className, token, startId);
16705        }
16706    }
16707
16708    @Override
16709    public void setServiceForeground(ComponentName className, IBinder token,
16710            int id, Notification notification, int flags) {
16711        synchronized(this) {
16712            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
16713        }
16714    }
16715
16716    @Override
16717    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16718            boolean requireFull, String name, String callerPackage) {
16719        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
16720                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16721    }
16722
16723    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16724            String className, int flags) {
16725        boolean result = false;
16726        // For apps that don't have pre-defined UIDs, check for permission
16727        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16728            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16729                if (ActivityManager.checkUidPermission(
16730                        INTERACT_ACROSS_USERS,
16731                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16732                    ComponentName comp = new ComponentName(aInfo.packageName, className);
16733                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
16734                            + " requests FLAG_SINGLE_USER, but app does not hold "
16735                            + INTERACT_ACROSS_USERS;
16736                    Slog.w(TAG, msg);
16737                    throw new SecurityException(msg);
16738                }
16739                // Permission passed
16740                result = true;
16741            }
16742        } else if ("system".equals(componentProcessName)) {
16743            result = true;
16744        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16745            // Phone app and persistent apps are allowed to export singleuser providers.
16746            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
16747                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
16748        }
16749        if (DEBUG_MU) Slog.v(TAG_MU,
16750                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
16751                + Integer.toHexString(flags) + ") = " + result);
16752        return result;
16753    }
16754
16755    /**
16756     * Checks to see if the caller is in the same app as the singleton
16757     * component, or the component is in a special app. It allows special apps
16758     * to export singleton components but prevents exporting singleton
16759     * components for regular apps.
16760     */
16761    boolean isValidSingletonCall(int callingUid, int componentUid) {
16762        int componentAppId = UserHandle.getAppId(componentUid);
16763        return UserHandle.isSameApp(callingUid, componentUid)
16764                || componentAppId == Process.SYSTEM_UID
16765                || componentAppId == Process.PHONE_UID
16766                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
16767                        == PackageManager.PERMISSION_GRANTED;
16768    }
16769
16770    public int bindService(IApplicationThread caller, IBinder token, Intent service,
16771            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
16772            int userId) throws TransactionTooLargeException {
16773        enforceNotIsolatedCaller("bindService");
16774
16775        // Refuse possible leaked file descriptors
16776        if (service != null && service.hasFileDescriptors() == true) {
16777            throw new IllegalArgumentException("File descriptors passed in Intent");
16778        }
16779
16780        if (callingPackage == null) {
16781            throw new IllegalArgumentException("callingPackage cannot be null");
16782        }
16783
16784        synchronized(this) {
16785            return mServices.bindServiceLocked(caller, token, service,
16786                    resolvedType, connection, flags, callingPackage, userId);
16787        }
16788    }
16789
16790    public boolean unbindService(IServiceConnection connection) {
16791        synchronized (this) {
16792            return mServices.unbindServiceLocked(connection);
16793        }
16794    }
16795
16796    public void publishService(IBinder token, Intent intent, IBinder service) {
16797        // Refuse possible leaked file descriptors
16798        if (intent != null && intent.hasFileDescriptors() == true) {
16799            throw new IllegalArgumentException("File descriptors passed in Intent");
16800        }
16801
16802        synchronized(this) {
16803            if (!(token instanceof ServiceRecord)) {
16804                throw new IllegalArgumentException("Invalid service token");
16805            }
16806            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
16807        }
16808    }
16809
16810    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
16811        // Refuse possible leaked file descriptors
16812        if (intent != null && intent.hasFileDescriptors() == true) {
16813            throw new IllegalArgumentException("File descriptors passed in Intent");
16814        }
16815
16816        synchronized(this) {
16817            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
16818        }
16819    }
16820
16821    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
16822        synchronized(this) {
16823            if (!(token instanceof ServiceRecord)) {
16824                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
16825                throw new IllegalArgumentException("Invalid service token");
16826            }
16827            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
16828        }
16829    }
16830
16831    // =========================================================
16832    // BACKUP AND RESTORE
16833    // =========================================================
16834
16835    // Cause the target app to be launched if necessary and its backup agent
16836    // instantiated.  The backup agent will invoke backupAgentCreated() on the
16837    // activity manager to announce its creation.
16838    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
16839        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
16840                "bindBackupAgent: app=" + app + " mode=" + backupMode);
16841        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
16842
16843        synchronized(this) {
16844            // !!! TODO: currently no check here that we're already bound
16845            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
16846            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16847            synchronized (stats) {
16848                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
16849            }
16850
16851            // Backup agent is now in use, its package can't be stopped.
16852            try {
16853                AppGlobals.getPackageManager().setPackageStoppedState(
16854                        app.packageName, false, UserHandle.getUserId(app.uid));
16855            } catch (RemoteException e) {
16856            } catch (IllegalArgumentException e) {
16857                Slog.w(TAG, "Failed trying to unstop package "
16858                        + app.packageName + ": " + e);
16859            }
16860
16861            BackupRecord r = new BackupRecord(ss, app, backupMode);
16862            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
16863                    ? new ComponentName(app.packageName, app.backupAgentName)
16864                    : new ComponentName("android", "FullBackupAgent");
16865            // startProcessLocked() returns existing proc's record if it's already running
16866            ProcessRecord proc = startProcessLocked(app.processName, app,
16867                    false, 0, "backup", hostingName, false, false, false);
16868            if (proc == null) {
16869                Slog.e(TAG, "Unable to start backup agent process " + r);
16870                return false;
16871            }
16872
16873            // If the app is a regular app (uid >= 10000) and not the system server or phone
16874            // process, etc, then mark it as being in full backup so that certain calls to the
16875            // process can be blocked. This is not reset to false anywhere because we kill the
16876            // process after the full backup is done and the ProcessRecord will vaporize anyway.
16877            if (UserHandle.isApp(app.uid) && backupMode == IApplicationThread.BACKUP_MODE_FULL) {
16878                proc.inFullBackup = true;
16879            }
16880            r.app = proc;
16881            mBackupTarget = r;
16882            mBackupAppName = app.packageName;
16883
16884            // Try not to kill the process during backup
16885            updateOomAdjLocked(proc);
16886
16887            // If the process is already attached, schedule the creation of the backup agent now.
16888            // If it is not yet live, this will be done when it attaches to the framework.
16889            if (proc.thread != null) {
16890                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16891                try {
16892                    proc.thread.scheduleCreateBackupAgent(app,
16893                            compatibilityInfoForPackageLocked(app), backupMode);
16894                } catch (RemoteException e) {
16895                    // Will time out on the backup manager side
16896                }
16897            } else {
16898                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16899            }
16900            // Invariants: at this point, the target app process exists and the application
16901            // is either already running or in the process of coming up.  mBackupTarget and
16902            // mBackupAppName describe the app, so that when it binds back to the AM we
16903            // know that it's scheduled for a backup-agent operation.
16904        }
16905
16906        return true;
16907    }
16908
16909    @Override
16910    public void clearPendingBackup() {
16911        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16912        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16913
16914        synchronized (this) {
16915            mBackupTarget = null;
16916            mBackupAppName = null;
16917        }
16918    }
16919
16920    // A backup agent has just come up
16921    public void backupAgentCreated(String agentPackageName, IBinder agent) {
16922        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16923                + " = " + agent);
16924
16925        synchronized(this) {
16926            if (!agentPackageName.equals(mBackupAppName)) {
16927                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
16928                return;
16929            }
16930        }
16931
16932        long oldIdent = Binder.clearCallingIdentity();
16933        try {
16934            IBackupManager bm = IBackupManager.Stub.asInterface(
16935                    ServiceManager.getService(Context.BACKUP_SERVICE));
16936            bm.agentConnected(agentPackageName, agent);
16937        } catch (RemoteException e) {
16938            // can't happen; the backup manager service is local
16939        } catch (Exception e) {
16940            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
16941            e.printStackTrace();
16942        } finally {
16943            Binder.restoreCallingIdentity(oldIdent);
16944        }
16945    }
16946
16947    // done with this agent
16948    public void unbindBackupAgent(ApplicationInfo appInfo) {
16949        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
16950        if (appInfo == null) {
16951            Slog.w(TAG, "unbind backup agent for null app");
16952            return;
16953        }
16954
16955        synchronized(this) {
16956            try {
16957                if (mBackupAppName == null) {
16958                    Slog.w(TAG, "Unbinding backup agent with no active backup");
16959                    return;
16960                }
16961
16962                if (!mBackupAppName.equals(appInfo.packageName)) {
16963                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
16964                    return;
16965                }
16966
16967                // Not backing this app up any more; reset its OOM adjustment
16968                final ProcessRecord proc = mBackupTarget.app;
16969                updateOomAdjLocked(proc);
16970
16971                // If the app crashed during backup, 'thread' will be null here
16972                if (proc.thread != null) {
16973                    try {
16974                        proc.thread.scheduleDestroyBackupAgent(appInfo,
16975                                compatibilityInfoForPackageLocked(appInfo));
16976                    } catch (Exception e) {
16977                        Slog.e(TAG, "Exception when unbinding backup agent:");
16978                        e.printStackTrace();
16979                    }
16980                }
16981            } finally {
16982                mBackupTarget = null;
16983                mBackupAppName = null;
16984            }
16985        }
16986    }
16987    // =========================================================
16988    // BROADCASTS
16989    // =========================================================
16990
16991    boolean isPendingBroadcastProcessLocked(int pid) {
16992        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
16993                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
16994    }
16995
16996    void skipPendingBroadcastLocked(int pid) {
16997            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
16998            for (BroadcastQueue queue : mBroadcastQueues) {
16999                queue.skipPendingBroadcastLocked(pid);
17000            }
17001    }
17002
17003    // The app just attached; send any pending broadcasts that it should receive
17004    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
17005        boolean didSomething = false;
17006        for (BroadcastQueue queue : mBroadcastQueues) {
17007            didSomething |= queue.sendPendingBroadcastsLocked(app);
17008        }
17009        return didSomething;
17010    }
17011
17012    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
17013            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17014        enforceNotIsolatedCaller("registerReceiver");
17015        ArrayList<Intent> stickyIntents = null;
17016        ProcessRecord callerApp = null;
17017        int callingUid;
17018        int callingPid;
17019        synchronized(this) {
17020            if (caller != null) {
17021                callerApp = getRecordForAppLocked(caller);
17022                if (callerApp == null) {
17023                    throw new SecurityException(
17024                            "Unable to find app for caller " + caller
17025                            + " (pid=" + Binder.getCallingPid()
17026                            + ") when registering receiver " + receiver);
17027                }
17028                if (callerApp.info.uid != Process.SYSTEM_UID &&
17029                        !callerApp.pkgList.containsKey(callerPackage) &&
17030                        !"android".equals(callerPackage)) {
17031                    throw new SecurityException("Given caller package " + callerPackage
17032                            + " is not running in process " + callerApp);
17033                }
17034                callingUid = callerApp.info.uid;
17035                callingPid = callerApp.pid;
17036            } else {
17037                callerPackage = null;
17038                callingUid = Binder.getCallingUid();
17039                callingPid = Binder.getCallingPid();
17040            }
17041
17042            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17043                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17044
17045            Iterator<String> actions = filter.actionsIterator();
17046            if (actions == null) {
17047                ArrayList<String> noAction = new ArrayList<String>(1);
17048                noAction.add(null);
17049                actions = noAction.iterator();
17050            }
17051
17052            // Collect stickies of users
17053            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17054            while (actions.hasNext()) {
17055                String action = actions.next();
17056                for (int id : userIds) {
17057                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17058                    if (stickies != null) {
17059                        ArrayList<Intent> intents = stickies.get(action);
17060                        if (intents != null) {
17061                            if (stickyIntents == null) {
17062                                stickyIntents = new ArrayList<Intent>();
17063                            }
17064                            stickyIntents.addAll(intents);
17065                        }
17066                    }
17067                }
17068            }
17069        }
17070
17071        ArrayList<Intent> allSticky = null;
17072        if (stickyIntents != null) {
17073            final ContentResolver resolver = mContext.getContentResolver();
17074            // Look for any matching sticky broadcasts...
17075            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17076                Intent intent = stickyIntents.get(i);
17077                // If intent has scheme "content", it will need to acccess
17078                // provider that needs to lock mProviderMap in ActivityThread
17079                // and also it may need to wait application response, so we
17080                // cannot lock ActivityManagerService here.
17081                if (filter.match(resolver, intent, true, TAG) >= 0) {
17082                    if (allSticky == null) {
17083                        allSticky = new ArrayList<Intent>();
17084                    }
17085                    allSticky.add(intent);
17086                }
17087            }
17088        }
17089
17090        // The first sticky in the list is returned directly back to the client.
17091        Intent sticky = allSticky != null ? allSticky.get(0) : null;
17092        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17093        if (receiver == null) {
17094            return sticky;
17095        }
17096
17097        synchronized (this) {
17098            if (callerApp != null && (callerApp.thread == null
17099                    || callerApp.thread.asBinder() != caller.asBinder())) {
17100                // Original caller already died
17101                return null;
17102            }
17103            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17104            if (rl == null) {
17105                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17106                        userId, receiver);
17107                if (rl.app != null) {
17108                    rl.app.receivers.add(rl);
17109                } else {
17110                    try {
17111                        receiver.asBinder().linkToDeath(rl, 0);
17112                    } catch (RemoteException e) {
17113                        return sticky;
17114                    }
17115                    rl.linkedToDeath = true;
17116                }
17117                mRegisteredReceivers.put(receiver.asBinder(), rl);
17118            } else if (rl.uid != callingUid) {
17119                throw new IllegalArgumentException(
17120                        "Receiver requested to register for uid " + callingUid
17121                        + " was previously registered for uid " + rl.uid);
17122            } else if (rl.pid != callingPid) {
17123                throw new IllegalArgumentException(
17124                        "Receiver requested to register for pid " + callingPid
17125                        + " was previously registered for pid " + rl.pid);
17126            } else if (rl.userId != userId) {
17127                throw new IllegalArgumentException(
17128                        "Receiver requested to register for user " + userId
17129                        + " was previously registered for user " + rl.userId);
17130            }
17131            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17132                    permission, callingUid, userId);
17133            rl.add(bf);
17134            if (!bf.debugCheck()) {
17135                Slog.w(TAG, "==> For Dynamic broadcast");
17136            }
17137            mReceiverResolver.addFilter(bf);
17138
17139            // Enqueue broadcasts for all existing stickies that match
17140            // this filter.
17141            if (allSticky != null) {
17142                ArrayList receivers = new ArrayList();
17143                receivers.add(bf);
17144
17145                final int stickyCount = allSticky.size();
17146                for (int i = 0; i < stickyCount; i++) {
17147                    Intent intent = allSticky.get(i);
17148                    BroadcastQueue queue = broadcastQueueForIntent(intent);
17149                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17150                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17151                            null, 0, null, null, false, true, true, -1);
17152                    queue.enqueueParallelBroadcastLocked(r);
17153                    queue.scheduleBroadcastsLocked();
17154                }
17155            }
17156
17157            return sticky;
17158        }
17159    }
17160
17161    public void unregisterReceiver(IIntentReceiver receiver) {
17162        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17163
17164        final long origId = Binder.clearCallingIdentity();
17165        try {
17166            boolean doTrim = false;
17167
17168            synchronized(this) {
17169                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17170                if (rl != null) {
17171                    final BroadcastRecord r = rl.curBroadcast;
17172                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17173                        final boolean doNext = r.queue.finishReceiverLocked(
17174                                r, r.resultCode, r.resultData, r.resultExtras,
17175                                r.resultAbort, false);
17176                        if (doNext) {
17177                            doTrim = true;
17178                            r.queue.processNextBroadcast(false);
17179                        }
17180                    }
17181
17182                    if (rl.app != null) {
17183                        rl.app.receivers.remove(rl);
17184                    }
17185                    removeReceiverLocked(rl);
17186                    if (rl.linkedToDeath) {
17187                        rl.linkedToDeath = false;
17188                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
17189                    }
17190                }
17191            }
17192
17193            // If we actually concluded any broadcasts, we might now be able
17194            // to trim the recipients' apps from our working set
17195            if (doTrim) {
17196                trimApplications();
17197                return;
17198            }
17199
17200        } finally {
17201            Binder.restoreCallingIdentity(origId);
17202        }
17203    }
17204
17205    void removeReceiverLocked(ReceiverList rl) {
17206        mRegisteredReceivers.remove(rl.receiver.asBinder());
17207        for (int i = rl.size() - 1; i >= 0; i--) {
17208            mReceiverResolver.removeFilter(rl.get(i));
17209        }
17210    }
17211
17212    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17213        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17214            ProcessRecord r = mLruProcesses.get(i);
17215            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17216                try {
17217                    r.thread.dispatchPackageBroadcast(cmd, packages);
17218                } catch (RemoteException ex) {
17219                }
17220            }
17221        }
17222    }
17223
17224    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17225            int callingUid, int[] users) {
17226        // TODO: come back and remove this assumption to triage all broadcasts
17227        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17228
17229        List<ResolveInfo> receivers = null;
17230        try {
17231            HashSet<ComponentName> singleUserReceivers = null;
17232            boolean scannedFirstReceivers = false;
17233            for (int user : users) {
17234                // Skip users that have Shell restrictions, with exception of always permitted
17235                // Shell broadcasts
17236                if (callingUid == Process.SHELL_UID
17237                        && mUserController.hasUserRestriction(
17238                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17239                        && !isPermittedShellBroadcast(intent)) {
17240                    continue;
17241                }
17242                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17243                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17244                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17245                    // If this is not the system user, we need to check for
17246                    // any receivers that should be filtered out.
17247                    for (int i=0; i<newReceivers.size(); i++) {
17248                        ResolveInfo ri = newReceivers.get(i);
17249                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17250                            newReceivers.remove(i);
17251                            i--;
17252                        }
17253                    }
17254                }
17255                if (newReceivers != null && newReceivers.size() == 0) {
17256                    newReceivers = null;
17257                }
17258                if (receivers == null) {
17259                    receivers = newReceivers;
17260                } else if (newReceivers != null) {
17261                    // We need to concatenate the additional receivers
17262                    // found with what we have do far.  This would be easy,
17263                    // but we also need to de-dup any receivers that are
17264                    // singleUser.
17265                    if (!scannedFirstReceivers) {
17266                        // Collect any single user receivers we had already retrieved.
17267                        scannedFirstReceivers = true;
17268                        for (int i=0; i<receivers.size(); i++) {
17269                            ResolveInfo ri = receivers.get(i);
17270                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17271                                ComponentName cn = new ComponentName(
17272                                        ri.activityInfo.packageName, ri.activityInfo.name);
17273                                if (singleUserReceivers == null) {
17274                                    singleUserReceivers = new HashSet<ComponentName>();
17275                                }
17276                                singleUserReceivers.add(cn);
17277                            }
17278                        }
17279                    }
17280                    // Add the new results to the existing results, tracking
17281                    // and de-dupping single user receivers.
17282                    for (int i=0; i<newReceivers.size(); i++) {
17283                        ResolveInfo ri = newReceivers.get(i);
17284                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17285                            ComponentName cn = new ComponentName(
17286                                    ri.activityInfo.packageName, ri.activityInfo.name);
17287                            if (singleUserReceivers == null) {
17288                                singleUserReceivers = new HashSet<ComponentName>();
17289                            }
17290                            if (!singleUserReceivers.contains(cn)) {
17291                                singleUserReceivers.add(cn);
17292                                receivers.add(ri);
17293                            }
17294                        } else {
17295                            receivers.add(ri);
17296                        }
17297                    }
17298                }
17299            }
17300        } catch (RemoteException ex) {
17301            // pm is in same process, this will never happen.
17302        }
17303        return receivers;
17304    }
17305
17306    private boolean isPermittedShellBroadcast(Intent intent) {
17307        // remote bugreport should always be allowed to be taken
17308        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17309    }
17310
17311    final int broadcastIntentLocked(ProcessRecord callerApp,
17312            String callerPackage, Intent intent, String resolvedType,
17313            IIntentReceiver resultTo, int resultCode, String resultData,
17314            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17315            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17316        intent = new Intent(intent);
17317
17318        // By default broadcasts do not go to stopped apps.
17319        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17320
17321        // If we have not finished booting, don't allow this to launch new processes.
17322        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17323            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17324        }
17325
17326        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17327                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17328                + " ordered=" + ordered + " userid=" + userId);
17329        if ((resultTo != null) && !ordered) {
17330            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17331        }
17332
17333        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17334                ALLOW_NON_FULL, "broadcast", callerPackage);
17335
17336        // Make sure that the user who is receiving this broadcast is running.
17337        // If not, we will just skip it. Make an exception for shutdown broadcasts
17338        // and upgrade steps.
17339
17340        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17341            if ((callingUid != Process.SYSTEM_UID
17342                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17343                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17344                Slog.w(TAG, "Skipping broadcast of " + intent
17345                        + ": user " + userId + " is stopped");
17346                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17347            }
17348        }
17349
17350        BroadcastOptions brOptions = null;
17351        if (bOptions != null) {
17352            brOptions = new BroadcastOptions(bOptions);
17353            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17354                // See if the caller is allowed to do this.  Note we are checking against
17355                // the actual real caller (not whoever provided the operation as say a
17356                // PendingIntent), because that who is actually supplied the arguments.
17357                if (checkComponentPermission(
17358                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17359                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17360                        != PackageManager.PERMISSION_GRANTED) {
17361                    String msg = "Permission Denial: " + intent.getAction()
17362                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17363                            + ", uid=" + callingUid + ")"
17364                            + " requires "
17365                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17366                    Slog.w(TAG, msg);
17367                    throw new SecurityException(msg);
17368                }
17369            }
17370        }
17371
17372        // Verify that protected broadcasts are only being sent by system code,
17373        // and that system code is only sending protected broadcasts.
17374        final String action = intent.getAction();
17375        final boolean isProtectedBroadcast;
17376        try {
17377            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17378        } catch (RemoteException e) {
17379            Slog.w(TAG, "Remote exception", e);
17380            return ActivityManager.BROADCAST_SUCCESS;
17381        }
17382
17383        final boolean isCallerSystem;
17384        switch (UserHandle.getAppId(callingUid)) {
17385            case Process.ROOT_UID:
17386            case Process.SYSTEM_UID:
17387            case Process.PHONE_UID:
17388            case Process.BLUETOOTH_UID:
17389            case Process.NFC_UID:
17390                isCallerSystem = true;
17391                break;
17392            default:
17393                isCallerSystem = (callerApp != null) && callerApp.persistent;
17394                break;
17395        }
17396
17397        if (isCallerSystem) {
17398            if (isProtectedBroadcast
17399                    || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17400                    || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17401                    || Intent.ACTION_MEDIA_BUTTON.equals(action)
17402                    || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17403                    || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17404                    || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17405                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17406                    || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
17407                    || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
17408                    || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
17409                // Broadcast is either protected, or it's a public action that
17410                // we've relaxed, so it's fine for system internals to send.
17411            } else {
17412                // The vast majority of broadcasts sent from system internals
17413                // should be protected to avoid security holes, so yell loudly
17414                // to ensure we examine these cases.
17415                if (callerApp != null) {
17416                    Log.wtf(TAG, "Sending non-protected broadcast " + action
17417                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
17418                            new Throwable());
17419                } else {
17420                    Log.wtf(TAG, "Sending non-protected broadcast " + action
17421                            + " from system uid " + UserHandle.formatUid(callingUid)
17422                            + " pkg " + callerPackage,
17423                            new Throwable());
17424                }
17425            }
17426
17427        } else {
17428            if (isProtectedBroadcast) {
17429                String msg = "Permission Denial: not allowed to send broadcast "
17430                        + action + " from pid="
17431                        + callingPid + ", uid=" + callingUid;
17432                Slog.w(TAG, msg);
17433                throw new SecurityException(msg);
17434
17435            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17436                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17437                // Special case for compatibility: we don't want apps to send this,
17438                // but historically it has not been protected and apps may be using it
17439                // to poke their own app widget.  So, instead of making it protected,
17440                // just limit it to the caller.
17441                if (callerPackage == null) {
17442                    String msg = "Permission Denial: not allowed to send broadcast "
17443                            + action + " from unknown caller.";
17444                    Slog.w(TAG, msg);
17445                    throw new SecurityException(msg);
17446                } else if (intent.getComponent() != null) {
17447                    // They are good enough to send to an explicit component...  verify
17448                    // it is being sent to the calling app.
17449                    if (!intent.getComponent().getPackageName().equals(
17450                            callerPackage)) {
17451                        String msg = "Permission Denial: not allowed to send broadcast "
17452                                + action + " to "
17453                                + intent.getComponent().getPackageName() + " from "
17454                                + callerPackage;
17455                        Slog.w(TAG, msg);
17456                        throw new SecurityException(msg);
17457                    }
17458                } else {
17459                    // Limit broadcast to their own package.
17460                    intent.setPackage(callerPackage);
17461                }
17462            }
17463        }
17464
17465        if (action != null) {
17466            switch (action) {
17467                case Intent.ACTION_UID_REMOVED:
17468                case Intent.ACTION_PACKAGE_REMOVED:
17469                case Intent.ACTION_PACKAGE_CHANGED:
17470                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17471                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17472                case Intent.ACTION_PACKAGES_SUSPENDED:
17473                case Intent.ACTION_PACKAGES_UNSUSPENDED:
17474                    // Handle special intents: if this broadcast is from the package
17475                    // manager about a package being removed, we need to remove all of
17476                    // its activities from the history stack.
17477                    if (checkComponentPermission(
17478                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17479                            callingPid, callingUid, -1, true)
17480                            != PackageManager.PERMISSION_GRANTED) {
17481                        String msg = "Permission Denial: " + intent.getAction()
17482                                + " broadcast from " + callerPackage + " (pid=" + callingPid
17483                                + ", uid=" + callingUid + ")"
17484                                + " requires "
17485                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17486                        Slog.w(TAG, msg);
17487                        throw new SecurityException(msg);
17488                    }
17489                    switch (action) {
17490                        case Intent.ACTION_UID_REMOVED:
17491                            final Bundle intentExtras = intent.getExtras();
17492                            final int uid = intentExtras != null
17493                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17494                            if (uid >= 0) {
17495                                mBatteryStatsService.removeUid(uid);
17496                                mAppOpsService.uidRemoved(uid);
17497                            }
17498                            break;
17499                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17500                            // If resources are unavailable just force stop all those packages
17501                            // and flush the attribute cache as well.
17502                            String list[] =
17503                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17504                            if (list != null && list.length > 0) {
17505                                for (int i = 0; i < list.length; i++) {
17506                                    forceStopPackageLocked(list[i], -1, false, true, true,
17507                                            false, false, userId, "storage unmount");
17508                                }
17509                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17510                                sendPackageBroadcastLocked(
17511                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17512                                        userId);
17513                            }
17514                            break;
17515                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17516                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17517                            break;
17518                        case Intent.ACTION_PACKAGE_REMOVED:
17519                        case Intent.ACTION_PACKAGE_CHANGED:
17520                            Uri data = intent.getData();
17521                            String ssp;
17522                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17523                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17524                                final boolean replacing =
17525                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17526                                final boolean killProcess =
17527                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17528                                final boolean fullUninstall = removed && !replacing;
17529                                if (removed) {
17530                                    if (killProcess) {
17531                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
17532                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
17533                                                false, true, true, false, fullUninstall, userId,
17534                                                removed ? "pkg removed" : "pkg changed");
17535                                    }
17536                                    final int cmd = killProcess
17537                                            ? IApplicationThread.PACKAGE_REMOVED
17538                                            : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
17539                                    sendPackageBroadcastLocked(cmd,
17540                                            new String[] {ssp}, userId);
17541                                    if (fullUninstall) {
17542                                        mAppOpsService.packageRemoved(
17543                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17544
17545                                        // Remove all permissions granted from/to this package
17546                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
17547
17548                                        removeTasksByPackageNameLocked(ssp, userId);
17549                                        mBatteryStatsService.notePackageUninstalled(ssp);
17550                                    }
17551                                } else {
17552                                    if (killProcess) {
17553                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
17554                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
17555                                                userId, ProcessList.INVALID_ADJ,
17556                                                false, true, true, false, "change " + ssp);
17557                                    }
17558                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17559                                            intent.getStringArrayExtra(
17560                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17561                                }
17562                            }
17563                            break;
17564                        case Intent.ACTION_PACKAGES_SUSPENDED:
17565                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
17566                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
17567                                    intent.getAction());
17568                            final String[] packageNames = intent.getStringArrayExtra(
17569                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
17570                            final int userHandle = intent.getIntExtra(
17571                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
17572
17573                            synchronized(ActivityManagerService.this) {
17574                                mRecentTasks.onPackagesSuspendedChanged(
17575                                        packageNames, suspended, userHandle);
17576                            }
17577                            break;
17578                    }
17579                    break;
17580                case Intent.ACTION_PACKAGE_REPLACED:
17581                {
17582                    final Uri data = intent.getData();
17583                    final String ssp;
17584                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17585                        final ApplicationInfo aInfo =
17586                                getPackageManagerInternalLocked().getApplicationInfo(
17587                                        ssp,
17588                                        userId);
17589                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
17590                        sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
17591                                new String[] {ssp}, userId);
17592                    }
17593                    break;
17594                }
17595                case Intent.ACTION_PACKAGE_ADDED:
17596                {
17597                    // Special case for adding a package: by default turn on compatibility mode.
17598                    Uri data = intent.getData();
17599                    String ssp;
17600                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17601                        final boolean replacing =
17602                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17603                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17604
17605                        try {
17606                            ApplicationInfo ai = AppGlobals.getPackageManager().
17607                                    getApplicationInfo(ssp, 0, 0);
17608                            mBatteryStatsService.notePackageInstalled(ssp,
17609                                    ai != null ? ai.versionCode : 0);
17610                        } catch (RemoteException e) {
17611                        }
17612                    }
17613                    break;
17614                }
17615                case Intent.ACTION_TIMEZONE_CHANGED:
17616                    // If this is the time zone changed action, queue up a message that will reset
17617                    // the timezone of all currently running processes. This message will get
17618                    // queued up before the broadcast happens.
17619                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17620                    break;
17621                case Intent.ACTION_TIME_CHANGED:
17622                    // If the user set the time, let all running processes know.
17623                    final int is24Hour =
17624                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17625                                    : 0;
17626                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17627                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17628                    synchronized (stats) {
17629                        stats.noteCurrentTimeChangedLocked();
17630                    }
17631                    break;
17632                case Intent.ACTION_CLEAR_DNS_CACHE:
17633                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17634                    break;
17635                case Proxy.PROXY_CHANGE_ACTION:
17636                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17637                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17638                    break;
17639                case android.hardware.Camera.ACTION_NEW_PICTURE:
17640                case android.hardware.Camera.ACTION_NEW_VIDEO:
17641                    // These broadcasts are no longer allowed by the system, since they can
17642                    // cause significant thrashing at a crictical point (using the camera).
17643                    // Apps should use JobScehduler to monitor for media provider changes.
17644                    Slog.w(TAG, action + " no longer allowed; dropping from "
17645                            + UserHandle.formatUid(callingUid));
17646                    // Lie; we don't want to crash the app.
17647                    return ActivityManager.BROADCAST_SUCCESS;
17648            }
17649        }
17650
17651        // Add to the sticky list if requested.
17652        if (sticky) {
17653            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17654                    callingPid, callingUid)
17655                    != PackageManager.PERMISSION_GRANTED) {
17656                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17657                        + callingPid + ", uid=" + callingUid
17658                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17659                Slog.w(TAG, msg);
17660                throw new SecurityException(msg);
17661            }
17662            if (requiredPermissions != null && requiredPermissions.length > 0) {
17663                Slog.w(TAG, "Can't broadcast sticky intent " + intent
17664                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
17665                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
17666            }
17667            if (intent.getComponent() != null) {
17668                throw new SecurityException(
17669                        "Sticky broadcasts can't target a specific component");
17670            }
17671            // We use userId directly here, since the "all" target is maintained
17672            // as a separate set of sticky broadcasts.
17673            if (userId != UserHandle.USER_ALL) {
17674                // But first, if this is not a broadcast to all users, then
17675                // make sure it doesn't conflict with an existing broadcast to
17676                // all users.
17677                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
17678                        UserHandle.USER_ALL);
17679                if (stickies != null) {
17680                    ArrayList<Intent> list = stickies.get(intent.getAction());
17681                    if (list != null) {
17682                        int N = list.size();
17683                        int i;
17684                        for (i=0; i<N; i++) {
17685                            if (intent.filterEquals(list.get(i))) {
17686                                throw new IllegalArgumentException(
17687                                        "Sticky broadcast " + intent + " for user "
17688                                        + userId + " conflicts with existing global broadcast");
17689                            }
17690                        }
17691                    }
17692                }
17693            }
17694            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17695            if (stickies == null) {
17696                stickies = new ArrayMap<>();
17697                mStickyBroadcasts.put(userId, stickies);
17698            }
17699            ArrayList<Intent> list = stickies.get(intent.getAction());
17700            if (list == null) {
17701                list = new ArrayList<>();
17702                stickies.put(intent.getAction(), list);
17703            }
17704            final int stickiesCount = list.size();
17705            int i;
17706            for (i = 0; i < stickiesCount; i++) {
17707                if (intent.filterEquals(list.get(i))) {
17708                    // This sticky already exists, replace it.
17709                    list.set(i, new Intent(intent));
17710                    break;
17711                }
17712            }
17713            if (i >= stickiesCount) {
17714                list.add(new Intent(intent));
17715            }
17716        }
17717
17718        int[] users;
17719        if (userId == UserHandle.USER_ALL) {
17720            // Caller wants broadcast to go to all started users.
17721            users = mUserController.getStartedUserArrayLocked();
17722        } else {
17723            // Caller wants broadcast to go to one specific user.
17724            users = new int[] {userId};
17725        }
17726
17727        // Figure out who all will receive this broadcast.
17728        List receivers = null;
17729        List<BroadcastFilter> registeredReceivers = null;
17730        // Need to resolve the intent to interested receivers...
17731        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
17732                 == 0) {
17733            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
17734        }
17735        if (intent.getComponent() == null) {
17736            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
17737                // Query one target user at a time, excluding shell-restricted users
17738                for (int i = 0; i < users.length; i++) {
17739                    if (mUserController.hasUserRestriction(
17740                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
17741                        continue;
17742                    }
17743                    List<BroadcastFilter> registeredReceiversForUser =
17744                            mReceiverResolver.queryIntent(intent,
17745                                    resolvedType, false, users[i]);
17746                    if (registeredReceivers == null) {
17747                        registeredReceivers = registeredReceiversForUser;
17748                    } else if (registeredReceiversForUser != null) {
17749                        registeredReceivers.addAll(registeredReceiversForUser);
17750                    }
17751                }
17752            } else {
17753                registeredReceivers = mReceiverResolver.queryIntent(intent,
17754                        resolvedType, false, userId);
17755            }
17756        }
17757
17758        final boolean replacePending =
17759                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
17760
17761        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
17762                + " replacePending=" + replacePending);
17763
17764        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
17765        if (!ordered && NR > 0) {
17766            // If we are not serializing this broadcast, then send the
17767            // registered receivers separately so they don't wait for the
17768            // components to be launched.
17769            final BroadcastQueue queue = broadcastQueueForIntent(intent);
17770            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17771                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
17772                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
17773                    resultExtras, ordered, sticky, false, userId);
17774            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
17775            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
17776            if (!replaced) {
17777                queue.enqueueParallelBroadcastLocked(r);
17778                queue.scheduleBroadcastsLocked();
17779            }
17780            registeredReceivers = null;
17781            NR = 0;
17782        }
17783
17784        // Merge into one list.
17785        int ir = 0;
17786        if (receivers != null) {
17787            // A special case for PACKAGE_ADDED: do not allow the package
17788            // being added to see this broadcast.  This prevents them from
17789            // using this as a back door to get run as soon as they are
17790            // installed.  Maybe in the future we want to have a special install
17791            // broadcast or such for apps, but we'd like to deliberately make
17792            // this decision.
17793            String skipPackages[] = null;
17794            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
17795                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
17796                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
17797                Uri data = intent.getData();
17798                if (data != null) {
17799                    String pkgName = data.getSchemeSpecificPart();
17800                    if (pkgName != null) {
17801                        skipPackages = new String[] { pkgName };
17802                    }
17803                }
17804            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
17805                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17806            }
17807            if (skipPackages != null && (skipPackages.length > 0)) {
17808                for (String skipPackage : skipPackages) {
17809                    if (skipPackage != null) {
17810                        int NT = receivers.size();
17811                        for (int it=0; it<NT; it++) {
17812                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
17813                            if (curt.activityInfo.packageName.equals(skipPackage)) {
17814                                receivers.remove(it);
17815                                it--;
17816                                NT--;
17817                            }
17818                        }
17819                    }
17820                }
17821            }
17822
17823            int NT = receivers != null ? receivers.size() : 0;
17824            int it = 0;
17825            ResolveInfo curt = null;
17826            BroadcastFilter curr = null;
17827            while (it < NT && ir < NR) {
17828                if (curt == null) {
17829                    curt = (ResolveInfo)receivers.get(it);
17830                }
17831                if (curr == null) {
17832                    curr = registeredReceivers.get(ir);
17833                }
17834                if (curr.getPriority() >= curt.priority) {
17835                    // Insert this broadcast record into the final list.
17836                    receivers.add(it, curr);
17837                    ir++;
17838                    curr = null;
17839                    it++;
17840                    NT++;
17841                } else {
17842                    // Skip to the next ResolveInfo in the final list.
17843                    it++;
17844                    curt = null;
17845                }
17846            }
17847        }
17848        while (ir < NR) {
17849            if (receivers == null) {
17850                receivers = new ArrayList();
17851            }
17852            receivers.add(registeredReceivers.get(ir));
17853            ir++;
17854        }
17855
17856        if ((receivers != null && receivers.size() > 0)
17857                || resultTo != null) {
17858            BroadcastQueue queue = broadcastQueueForIntent(intent);
17859            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17860                    callerPackage, callingPid, callingUid, resolvedType,
17861                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
17862                    resultData, resultExtras, ordered, sticky, false, userId);
17863
17864            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
17865                    + ": prev had " + queue.mOrderedBroadcasts.size());
17866            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
17867                    "Enqueueing broadcast " + r.intent.getAction());
17868
17869            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
17870            if (!replaced) {
17871                queue.enqueueOrderedBroadcastLocked(r);
17872                queue.scheduleBroadcastsLocked();
17873            }
17874        }
17875
17876        return ActivityManager.BROADCAST_SUCCESS;
17877    }
17878
17879    final Intent verifyBroadcastLocked(Intent intent) {
17880        // Refuse possible leaked file descriptors
17881        if (intent != null && intent.hasFileDescriptors() == true) {
17882            throw new IllegalArgumentException("File descriptors passed in Intent");
17883        }
17884
17885        int flags = intent.getFlags();
17886
17887        if (!mProcessesReady) {
17888            // if the caller really truly claims to know what they're doing, go
17889            // ahead and allow the broadcast without launching any receivers
17890            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
17891                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
17892            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
17893                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
17894                        + " before boot completion");
17895                throw new IllegalStateException("Cannot broadcast before boot completed");
17896            }
17897        }
17898
17899        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
17900            throw new IllegalArgumentException(
17901                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
17902        }
17903
17904        return intent;
17905    }
17906
17907    public final int broadcastIntent(IApplicationThread caller,
17908            Intent intent, String resolvedType, IIntentReceiver resultTo,
17909            int resultCode, String resultData, Bundle resultExtras,
17910            String[] requiredPermissions, int appOp, Bundle bOptions,
17911            boolean serialized, boolean sticky, int userId) {
17912        enforceNotIsolatedCaller("broadcastIntent");
17913        synchronized(this) {
17914            intent = verifyBroadcastLocked(intent);
17915
17916            final ProcessRecord callerApp = getRecordForAppLocked(caller);
17917            final int callingPid = Binder.getCallingPid();
17918            final int callingUid = Binder.getCallingUid();
17919            final long origId = Binder.clearCallingIdentity();
17920            int res = broadcastIntentLocked(callerApp,
17921                    callerApp != null ? callerApp.info.packageName : null,
17922                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
17923                    requiredPermissions, appOp, bOptions, serialized, sticky,
17924                    callingPid, callingUid, userId);
17925            Binder.restoreCallingIdentity(origId);
17926            return res;
17927        }
17928    }
17929
17930
17931    int broadcastIntentInPackage(String packageName, int uid,
17932            Intent intent, String resolvedType, IIntentReceiver resultTo,
17933            int resultCode, String resultData, Bundle resultExtras,
17934            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
17935            int userId) {
17936        synchronized(this) {
17937            intent = verifyBroadcastLocked(intent);
17938
17939            final long origId = Binder.clearCallingIdentity();
17940            String[] requiredPermissions = requiredPermission == null ? null
17941                    : new String[] {requiredPermission};
17942            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
17943                    resultTo, resultCode, resultData, resultExtras,
17944                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
17945                    sticky, -1, uid, userId);
17946            Binder.restoreCallingIdentity(origId);
17947            return res;
17948        }
17949    }
17950
17951    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
17952        // Refuse possible leaked file descriptors
17953        if (intent != null && intent.hasFileDescriptors() == true) {
17954            throw new IllegalArgumentException("File descriptors passed in Intent");
17955        }
17956
17957        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17958                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
17959
17960        synchronized(this) {
17961            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
17962                    != PackageManager.PERMISSION_GRANTED) {
17963                String msg = "Permission Denial: unbroadcastIntent() from pid="
17964                        + Binder.getCallingPid()
17965                        + ", uid=" + Binder.getCallingUid()
17966                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17967                Slog.w(TAG, msg);
17968                throw new SecurityException(msg);
17969            }
17970            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17971            if (stickies != null) {
17972                ArrayList<Intent> list = stickies.get(intent.getAction());
17973                if (list != null) {
17974                    int N = list.size();
17975                    int i;
17976                    for (i=0; i<N; i++) {
17977                        if (intent.filterEquals(list.get(i))) {
17978                            list.remove(i);
17979                            break;
17980                        }
17981                    }
17982                    if (list.size() <= 0) {
17983                        stickies.remove(intent.getAction());
17984                    }
17985                }
17986                if (stickies.size() <= 0) {
17987                    mStickyBroadcasts.remove(userId);
17988                }
17989            }
17990        }
17991    }
17992
17993    void backgroundServicesFinishedLocked(int userId) {
17994        for (BroadcastQueue queue : mBroadcastQueues) {
17995            queue.backgroundServicesFinishedLocked(userId);
17996        }
17997    }
17998
17999    public void finishReceiver(IBinder who, int resultCode, String resultData,
18000            Bundle resultExtras, boolean resultAbort, int flags) {
18001        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
18002
18003        // Refuse possible leaked file descriptors
18004        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
18005            throw new IllegalArgumentException("File descriptors passed in Bundle");
18006        }
18007
18008        final long origId = Binder.clearCallingIdentity();
18009        try {
18010            boolean doNext = false;
18011            BroadcastRecord r;
18012
18013            synchronized(this) {
18014                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
18015                        ? mFgBroadcastQueue : mBgBroadcastQueue;
18016                r = queue.getMatchingOrderedReceiver(who);
18017                if (r != null) {
18018                    doNext = r.queue.finishReceiverLocked(r, resultCode,
18019                        resultData, resultExtras, resultAbort, true);
18020                }
18021            }
18022
18023            if (doNext) {
18024                r.queue.processNextBroadcast(false);
18025            }
18026            trimApplications();
18027        } finally {
18028            Binder.restoreCallingIdentity(origId);
18029        }
18030    }
18031
18032    // =========================================================
18033    // INSTRUMENTATION
18034    // =========================================================
18035
18036    public boolean startInstrumentation(ComponentName className,
18037            String profileFile, int flags, Bundle arguments,
18038            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
18039            int userId, String abiOverride) {
18040        enforceNotIsolatedCaller("startInstrumentation");
18041        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18042                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
18043        // Refuse possible leaked file descriptors
18044        if (arguments != null && arguments.hasFileDescriptors()) {
18045            throw new IllegalArgumentException("File descriptors passed in Bundle");
18046        }
18047
18048        synchronized(this) {
18049            InstrumentationInfo ii = null;
18050            ApplicationInfo ai = null;
18051            try {
18052                ii = mContext.getPackageManager().getInstrumentationInfo(
18053                    className, STOCK_PM_FLAGS);
18054                ai = AppGlobals.getPackageManager().getApplicationInfo(
18055                        ii.targetPackage, STOCK_PM_FLAGS, userId);
18056            } catch (PackageManager.NameNotFoundException e) {
18057            } catch (RemoteException e) {
18058            }
18059            if (ii == null) {
18060                reportStartInstrumentationFailureLocked(watcher, className,
18061                        "Unable to find instrumentation info for: " + className);
18062                return false;
18063            }
18064            if (ai == null) {
18065                reportStartInstrumentationFailureLocked(watcher, className,
18066                        "Unable to find instrumentation target package: " + ii.targetPackage);
18067                return false;
18068            }
18069            if (!ai.hasCode()) {
18070                reportStartInstrumentationFailureLocked(watcher, className,
18071                        "Instrumentation target has no code: " + ii.targetPackage);
18072                return false;
18073            }
18074
18075            int match = mContext.getPackageManager().checkSignatures(
18076                    ii.targetPackage, ii.packageName);
18077            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18078                String msg = "Permission Denial: starting instrumentation "
18079                        + className + " from pid="
18080                        + Binder.getCallingPid()
18081                        + ", uid=" + Binder.getCallingPid()
18082                        + " not allowed because package " + ii.packageName
18083                        + " does not have a signature matching the target "
18084                        + ii.targetPackage;
18085                reportStartInstrumentationFailureLocked(watcher, className, msg);
18086                throw new SecurityException(msg);
18087            }
18088
18089            final long origId = Binder.clearCallingIdentity();
18090            // Instrumentation can kill and relaunch even persistent processes
18091            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18092                    "start instr");
18093            ProcessRecord app = addAppLocked(ai, false, abiOverride);
18094            app.instrumentationClass = className;
18095            app.instrumentationInfo = ai;
18096            app.instrumentationProfileFile = profileFile;
18097            app.instrumentationArguments = arguments;
18098            app.instrumentationWatcher = watcher;
18099            app.instrumentationUiAutomationConnection = uiAutomationConnection;
18100            app.instrumentationResultClass = className;
18101            Binder.restoreCallingIdentity(origId);
18102        }
18103
18104        return true;
18105    }
18106
18107    /**
18108     * Report errors that occur while attempting to start Instrumentation.  Always writes the
18109     * error to the logs, but if somebody is watching, send the report there too.  This enables
18110     * the "am" command to report errors with more information.
18111     *
18112     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
18113     * @param cn The component name of the instrumentation.
18114     * @param report The error report.
18115     */
18116    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18117            ComponentName cn, String report) {
18118        Slog.w(TAG, report);
18119        if (watcher != null) {
18120            Bundle results = new Bundle();
18121            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18122            results.putString("Error", report);
18123            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18124        }
18125    }
18126
18127    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18128        if (app.instrumentationWatcher != null) {
18129            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18130                    app.instrumentationClass, resultCode, results);
18131        }
18132
18133        // Can't call out of the system process with a lock held, so post a message.
18134        if (app.instrumentationUiAutomationConnection != null) {
18135            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18136                    app.instrumentationUiAutomationConnection).sendToTarget();
18137        }
18138
18139        app.instrumentationWatcher = null;
18140        app.instrumentationUiAutomationConnection = null;
18141        app.instrumentationClass = null;
18142        app.instrumentationInfo = null;
18143        app.instrumentationProfileFile = null;
18144        app.instrumentationArguments = null;
18145
18146        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18147                "finished inst");
18148    }
18149
18150    public void finishInstrumentation(IApplicationThread target,
18151            int resultCode, Bundle results) {
18152        int userId = UserHandle.getCallingUserId();
18153        // Refuse possible leaked file descriptors
18154        if (results != null && results.hasFileDescriptors()) {
18155            throw new IllegalArgumentException("File descriptors passed in Intent");
18156        }
18157
18158        synchronized(this) {
18159            ProcessRecord app = getRecordForAppLocked(target);
18160            if (app == null) {
18161                Slog.w(TAG, "finishInstrumentation: no app for " + target);
18162                return;
18163            }
18164            final long origId = Binder.clearCallingIdentity();
18165            finishInstrumentationLocked(app, resultCode, results);
18166            Binder.restoreCallingIdentity(origId);
18167        }
18168    }
18169
18170    // =========================================================
18171    // CONFIGURATION
18172    // =========================================================
18173
18174    public ConfigurationInfo getDeviceConfigurationInfo() {
18175        ConfigurationInfo config = new ConfigurationInfo();
18176        synchronized (this) {
18177            config.reqTouchScreen = mConfiguration.touchscreen;
18178            config.reqKeyboardType = mConfiguration.keyboard;
18179            config.reqNavigation = mConfiguration.navigation;
18180            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18181                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18182                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18183            }
18184            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18185                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18186                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18187            }
18188            config.reqGlEsVersion = GL_ES_VERSION;
18189        }
18190        return config;
18191    }
18192
18193    ActivityStack getFocusedStack() {
18194        return mStackSupervisor.getFocusedStack();
18195    }
18196
18197    @Override
18198    public int getFocusedStackId() throws RemoteException {
18199        ActivityStack focusedStack = getFocusedStack();
18200        if (focusedStack != null) {
18201            return focusedStack.getStackId();
18202        }
18203        return -1;
18204    }
18205
18206    public Configuration getConfiguration() {
18207        Configuration ci;
18208        synchronized(this) {
18209            ci = new Configuration(mConfiguration);
18210            ci.userSetLocale = false;
18211        }
18212        return ci;
18213    }
18214
18215    @Override
18216    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18217        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18218        synchronized (this) {
18219            mSuppressResizeConfigChanges = suppress;
18220        }
18221    }
18222
18223    @Override
18224    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18225        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18226        if (fromStackId == HOME_STACK_ID) {
18227            throw new IllegalArgumentException("You can't move tasks from the home stack.");
18228        }
18229        synchronized (this) {
18230            final long origId = Binder.clearCallingIdentity();
18231            try {
18232                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18233            } finally {
18234                Binder.restoreCallingIdentity(origId);
18235            }
18236        }
18237    }
18238
18239    @Override
18240    public void updatePersistentConfiguration(Configuration values) {
18241        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18242                "updateConfiguration()");
18243        enforceWriteSettingsPermission("updateConfiguration()");
18244        if (values == null) {
18245            throw new NullPointerException("Configuration must not be null");
18246        }
18247
18248        int userId = UserHandle.getCallingUserId();
18249
18250        synchronized(this) {
18251            final long origId = Binder.clearCallingIdentity();
18252            updateConfigurationLocked(values, null, false, true, userId);
18253            Binder.restoreCallingIdentity(origId);
18254        }
18255    }
18256
18257    private void updateFontScaleIfNeeded() {
18258        final int currentUserId;
18259        synchronized(this) {
18260            currentUserId = mUserController.getCurrentUserIdLocked();
18261        }
18262        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18263                FONT_SCALE, 1.0f, currentUserId);
18264        if (mConfiguration.fontScale != scaleFactor) {
18265            final Configuration configuration = mWindowManager.computeNewConfiguration();
18266            configuration.fontScale = scaleFactor;
18267            updatePersistentConfiguration(configuration);
18268        }
18269    }
18270
18271    private void enforceWriteSettingsPermission(String func) {
18272        int uid = Binder.getCallingUid();
18273        if (uid == Process.ROOT_UID) {
18274            return;
18275        }
18276
18277        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18278                Settings.getPackageNameForUid(mContext, uid), false)) {
18279            return;
18280        }
18281
18282        String msg = "Permission Denial: " + func + " from pid="
18283                + Binder.getCallingPid()
18284                + ", uid=" + uid
18285                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18286        Slog.w(TAG, msg);
18287        throw new SecurityException(msg);
18288    }
18289
18290    public void updateConfiguration(Configuration values) {
18291        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18292                "updateConfiguration()");
18293
18294        synchronized(this) {
18295            if (values == null && mWindowManager != null) {
18296                // sentinel: fetch the current configuration from the window manager
18297                values = mWindowManager.computeNewConfiguration();
18298            }
18299
18300            if (mWindowManager != null) {
18301                mProcessList.applyDisplaySize(mWindowManager);
18302            }
18303
18304            final long origId = Binder.clearCallingIdentity();
18305            if (values != null) {
18306                Settings.System.clearConfiguration(values);
18307            }
18308            updateConfigurationLocked(values, null, false);
18309            Binder.restoreCallingIdentity(origId);
18310        }
18311    }
18312
18313    void updateUserConfigurationLocked() {
18314        Configuration configuration = new Configuration(mConfiguration);
18315        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
18316                mUserController.getCurrentUserIdLocked(), Settings.System.canWrite(mContext));
18317        updateConfigurationLocked(configuration, null, false);
18318    }
18319
18320    boolean updateConfigurationLocked(Configuration values,
18321            ActivityRecord starting, boolean initLocale) {
18322        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18323        return updateConfigurationLocked(values, starting, initLocale, false,
18324                UserHandle.USER_NULL);
18325    }
18326
18327    // To cache the list of supported system locales
18328    private String[] mSupportedSystemLocales = null;
18329
18330    /**
18331     * Do either or both things: (1) change the current configuration, and (2)
18332     * make sure the given activity is running with the (now) current
18333     * configuration.  Returns true if the activity has been left running, or
18334     * false if <var>starting</var> is being destroyed to match the new
18335     * configuration.
18336     *
18337     * @param userId is only used when persistent parameter is set to true to persist configuration
18338     *               for that particular user
18339     */
18340    private boolean updateConfigurationLocked(Configuration values,
18341            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
18342        int changes = 0;
18343
18344        if (mWindowManager != null) {
18345            mWindowManager.deferSurfaceLayout();
18346        }
18347        if (values != null) {
18348            Configuration newConfig = new Configuration(mConfiguration);
18349            changes = newConfig.updateFrom(values);
18350            if (changes != 0) {
18351                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18352                        "Updating configuration to: " + values);
18353
18354                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18355
18356                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18357                    final LocaleList locales = values.getLocales();
18358                    int bestLocaleIndex = 0;
18359                    if (locales.size() > 1) {
18360                        if (mSupportedSystemLocales == null) {
18361                            mSupportedSystemLocales =
18362                                    Resources.getSystem().getAssets().getLocales();
18363                        }
18364                        bestLocaleIndex = Math.max(0,
18365                                locales.getFirstMatchIndex(mSupportedSystemLocales));
18366                    }
18367                    SystemProperties.set("persist.sys.locale",
18368                            locales.get(bestLocaleIndex).toLanguageTag());
18369                    LocaleList.setDefault(locales, bestLocaleIndex);
18370                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18371                            locales.get(bestLocaleIndex)));
18372                }
18373
18374                mConfigurationSeq++;
18375                if (mConfigurationSeq <= 0) {
18376                    mConfigurationSeq = 1;
18377                }
18378                newConfig.seq = mConfigurationSeq;
18379                mConfiguration = newConfig;
18380                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18381                mUsageStatsService.reportConfigurationChange(newConfig,
18382                        mUserController.getCurrentUserIdLocked());
18383                //mUsageStatsService.noteStartConfig(newConfig);
18384
18385                final Configuration configCopy = new Configuration(mConfiguration);
18386
18387                // TODO: If our config changes, should we auto dismiss any currently
18388                // showing dialogs?
18389                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18390
18391                AttributeCache ac = AttributeCache.instance();
18392                if (ac != null) {
18393                    ac.updateConfiguration(configCopy);
18394                }
18395
18396                // Make sure all resources in our process are updated
18397                // right now, so that anyone who is going to retrieve
18398                // resource values after we return will be sure to get
18399                // the new ones.  This is especially important during
18400                // boot, where the first config change needs to guarantee
18401                // all resources have that config before following boot
18402                // code is executed.
18403                mSystemThread.applyConfigurationToResources(configCopy);
18404
18405                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18406                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18407                    msg.obj = new Configuration(configCopy);
18408                    msg.arg1 = userId;
18409                    mHandler.sendMessage(msg);
18410                }
18411
18412                final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
18413                if (isDensityChange) {
18414                    killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
18415                            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
18416                }
18417
18418                for (int i=mLruProcesses.size()-1; i>=0; i--) {
18419                    ProcessRecord app = mLruProcesses.get(i);
18420                    try {
18421                        if (app.thread != null) {
18422                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18423                                    + app.processName + " new config " + mConfiguration);
18424                            app.thread.scheduleConfigurationChanged(configCopy);
18425                        }
18426                    } catch (Exception e) {
18427                    }
18428                }
18429                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18430                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18431                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
18432                        | Intent.FLAG_RECEIVER_FOREGROUND);
18433                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18434                        null, AppOpsManager.OP_NONE, null, false, false,
18435                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18436                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18437                    // Tell the shortcut manager that the system locale changed.  It needs to know
18438                    // it before any other apps receive ACTION_LOCALE_CHANGED, which is why
18439                    // we "push" from here, rather than having the service listen to the broadcast.
18440                    final ShortcutServiceInternal shortcutService =
18441                            LocalServices.getService(ShortcutServiceInternal.class);
18442                    if (shortcutService != null) {
18443                        shortcutService.onSystemLocaleChangedNoLock();
18444                    }
18445
18446                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18447                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18448                    if (!mProcessesReady) {
18449                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18450                    }
18451                    broadcastIntentLocked(null, null, intent,
18452                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18453                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18454                }
18455            }
18456            // Update the configuration with WM first and check if any of the stacks need to be
18457            // resized due to the configuration change. If so, resize the stacks now and do any
18458            // relaunches if necessary. This way we don't need to relaunch again below in
18459            // ensureActivityConfigurationLocked().
18460            if (mWindowManager != null) {
18461                final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
18462                if (resizedStacks != null) {
18463                    for (int stackId : resizedStacks) {
18464                        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
18465                        mStackSupervisor.resizeStackLocked(
18466                                stackId, newBounds, null, null, false, false, !DEFER_RESUME);
18467                    }
18468                }
18469            }
18470        }
18471
18472        boolean kept = true;
18473        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18474        // mainStack is null during startup.
18475        if (mainStack != null) {
18476            if (changes != 0 && starting == null) {
18477                // If the configuration changed, and the caller is not already
18478                // in the process of starting an activity, then find the top
18479                // activity to check if its configuration needs to change.
18480                starting = mainStack.topRunningActivityLocked();
18481            }
18482
18483            if (starting != null) {
18484                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18485                // And we need to make sure at this point that all other activities
18486                // are made visible with the correct configuration.
18487                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18488                        !PRESERVE_WINDOWS);
18489            }
18490        }
18491        if (mWindowManager != null) {
18492            mWindowManager.continueSurfaceLayout();
18493        }
18494        return kept;
18495    }
18496
18497    /**
18498     * Decide based on the configuration whether we should shouw the ANR,
18499     * crash, etc dialogs.  The idea is that if there is no affordnace to
18500     * press the on-screen buttons, we shouldn't show the dialog.
18501     *
18502     * A thought: SystemUI might also want to get told about this, the Power
18503     * dialog / global actions also might want different behaviors.
18504     */
18505    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
18506        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18507                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18508                                   && config.navigation == Configuration.NAVIGATION_NONAV);
18509        final boolean uiIsNotCarType = !((config.uiMode & Configuration.UI_MODE_TYPE_MASK)
18510                                    == Configuration.UI_MODE_TYPE_CAR);
18511        return inputMethodExists && uiIsNotCarType && !inVrMode;
18512    }
18513
18514    @Override
18515    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18516        synchronized (this) {
18517            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18518            if (srec != null) {
18519                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18520            }
18521        }
18522        return false;
18523    }
18524
18525    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18526            Intent resultData) {
18527
18528        synchronized (this) {
18529            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18530            if (r != null) {
18531                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18532            }
18533            return false;
18534        }
18535    }
18536
18537    public int getLaunchedFromUid(IBinder activityToken) {
18538        ActivityRecord srec;
18539        synchronized (this) {
18540            srec = ActivityRecord.forTokenLocked(activityToken);
18541        }
18542        if (srec == null) {
18543            return -1;
18544        }
18545        return srec.launchedFromUid;
18546    }
18547
18548    public String getLaunchedFromPackage(IBinder activityToken) {
18549        ActivityRecord srec;
18550        synchronized (this) {
18551            srec = ActivityRecord.forTokenLocked(activityToken);
18552        }
18553        if (srec == null) {
18554            return null;
18555        }
18556        return srec.launchedFromPackage;
18557    }
18558
18559    // =========================================================
18560    // LIFETIME MANAGEMENT
18561    // =========================================================
18562
18563    // Returns which broadcast queue the app is the current [or imminent] receiver
18564    // on, or 'null' if the app is not an active broadcast recipient.
18565    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18566        BroadcastRecord r = app.curReceiver;
18567        if (r != null) {
18568            return r.queue;
18569        }
18570
18571        // It's not the current receiver, but it might be starting up to become one
18572        synchronized (this) {
18573            for (BroadcastQueue queue : mBroadcastQueues) {
18574                r = queue.mPendingBroadcast;
18575                if (r != null && r.curApp == app) {
18576                    // found it; report which queue it's in
18577                    return queue;
18578                }
18579            }
18580        }
18581
18582        return null;
18583    }
18584
18585    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
18586            int targetUid, ComponentName targetComponent, String targetProcess) {
18587        if (!mTrackingAssociations) {
18588            return null;
18589        }
18590        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18591                = mAssociations.get(targetUid);
18592        if (components == null) {
18593            components = new ArrayMap<>();
18594            mAssociations.put(targetUid, components);
18595        }
18596        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18597        if (sourceUids == null) {
18598            sourceUids = new SparseArray<>();
18599            components.put(targetComponent, sourceUids);
18600        }
18601        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18602        if (sourceProcesses == null) {
18603            sourceProcesses = new ArrayMap<>();
18604            sourceUids.put(sourceUid, sourceProcesses);
18605        }
18606        Association ass = sourceProcesses.get(sourceProcess);
18607        if (ass == null) {
18608            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
18609                    targetProcess);
18610            sourceProcesses.put(sourceProcess, ass);
18611        }
18612        ass.mCount++;
18613        ass.mNesting++;
18614        if (ass.mNesting == 1) {
18615            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
18616            ass.mLastState = sourceState;
18617        }
18618        return ass;
18619    }
18620
18621    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18622            ComponentName targetComponent) {
18623        if (!mTrackingAssociations) {
18624            return;
18625        }
18626        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18627                = mAssociations.get(targetUid);
18628        if (components == null) {
18629            return;
18630        }
18631        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18632        if (sourceUids == null) {
18633            return;
18634        }
18635        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18636        if (sourceProcesses == null) {
18637            return;
18638        }
18639        Association ass = sourceProcesses.get(sourceProcess);
18640        if (ass == null || ass.mNesting <= 0) {
18641            return;
18642        }
18643        ass.mNesting--;
18644        if (ass.mNesting == 0) {
18645            long uptime = SystemClock.uptimeMillis();
18646            ass.mTime += uptime - ass.mStartTime;
18647            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18648                    += uptime - ass.mLastStateUptime;
18649            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
18650        }
18651    }
18652
18653    private void noteUidProcessState(final int uid, final int state) {
18654        mBatteryStatsService.noteUidProcessState(uid, state);
18655        if (mTrackingAssociations) {
18656            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
18657                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
18658                        = mAssociations.valueAt(i1);
18659                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
18660                    SparseArray<ArrayMap<String, Association>> sourceUids
18661                            = targetComponents.valueAt(i2);
18662                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
18663                    if (sourceProcesses != null) {
18664                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
18665                            Association ass = sourceProcesses.valueAt(i4);
18666                            if (ass.mNesting >= 1) {
18667                                // currently associated
18668                                long uptime = SystemClock.uptimeMillis();
18669                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18670                                        += uptime - ass.mLastStateUptime;
18671                                ass.mLastState = state;
18672                                ass.mLastStateUptime = uptime;
18673                            }
18674                        }
18675                    }
18676                }
18677            }
18678        }
18679    }
18680
18681    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
18682            boolean doingAll, long now) {
18683        if (mAdjSeq == app.adjSeq) {
18684            // This adjustment has already been computed.
18685            return app.curRawAdj;
18686        }
18687
18688        if (app.thread == null) {
18689            app.adjSeq = mAdjSeq;
18690            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18691            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18692            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
18693        }
18694
18695        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
18696        app.adjSource = null;
18697        app.adjTarget = null;
18698        app.empty = false;
18699        app.cached = false;
18700
18701        final int activitiesSize = app.activities.size();
18702
18703        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
18704            // The max adjustment doesn't allow this app to be anything
18705            // below foreground, so it is not worth doing work for it.
18706            app.adjType = "fixed";
18707            app.adjSeq = mAdjSeq;
18708            app.curRawAdj = app.maxAdj;
18709            app.foregroundActivities = false;
18710            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18711            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
18712            // System processes can do UI, and when they do we want to have
18713            // them trim their memory after the user leaves the UI.  To
18714            // facilitate this, here we need to determine whether or not it
18715            // is currently showing UI.
18716            app.systemNoUi = true;
18717            if (app == TOP_APP) {
18718                app.systemNoUi = false;
18719                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18720                app.adjType = "pers-top-activity";
18721            } else if (activitiesSize > 0) {
18722                for (int j = 0; j < activitiesSize; j++) {
18723                    final ActivityRecord r = app.activities.get(j);
18724                    if (r.visible) {
18725                        app.systemNoUi = false;
18726                    }
18727                }
18728            }
18729            if (!app.systemNoUi) {
18730                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
18731            }
18732            return (app.curAdj=app.maxAdj);
18733        }
18734
18735        app.systemNoUi = false;
18736
18737        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
18738
18739        // Determine the importance of the process, starting with most
18740        // important to least, and assign an appropriate OOM adjustment.
18741        int adj;
18742        int schedGroup;
18743        int procState;
18744        boolean foregroundActivities = false;
18745        BroadcastQueue queue;
18746        if (app == TOP_APP) {
18747            // The last app on the list is the foreground app.
18748            adj = ProcessList.FOREGROUND_APP_ADJ;
18749            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18750            app.adjType = "top-activity";
18751            foregroundActivities = true;
18752            procState = PROCESS_STATE_CUR_TOP;
18753        } else if (app.instrumentationClass != null) {
18754            // Don't want to kill running instrumentation.
18755            adj = ProcessList.FOREGROUND_APP_ADJ;
18756            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18757            app.adjType = "instrumentation";
18758            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18759        } else if ((queue = isReceivingBroadcast(app)) != null) {
18760            // An app that is currently receiving a broadcast also
18761            // counts as being in the foreground for OOM killer purposes.
18762            // It's placed in a sched group based on the nature of the
18763            // broadcast as reflected by which queue it's active in.
18764            adj = ProcessList.FOREGROUND_APP_ADJ;
18765            schedGroup = (queue == mFgBroadcastQueue)
18766                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18767            app.adjType = "broadcast";
18768            procState = ActivityManager.PROCESS_STATE_RECEIVER;
18769        } else if (app.executingServices.size() > 0) {
18770            // An app that is currently executing a service callback also
18771            // counts as being in the foreground.
18772            adj = ProcessList.FOREGROUND_APP_ADJ;
18773            schedGroup = app.execServicesFg ?
18774                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18775            app.adjType = "exec-service";
18776            procState = ActivityManager.PROCESS_STATE_SERVICE;
18777            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
18778        } else {
18779            // As far as we know the process is empty.  We may change our mind later.
18780            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18781            // At this point we don't actually know the adjustment.  Use the cached adj
18782            // value that the caller wants us to.
18783            adj = cachedAdj;
18784            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18785            app.cached = true;
18786            app.empty = true;
18787            app.adjType = "cch-empty";
18788        }
18789
18790        // Examine all activities if not already foreground.
18791        if (!foregroundActivities && activitiesSize > 0) {
18792            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
18793            for (int j = 0; j < activitiesSize; j++) {
18794                final ActivityRecord r = app.activities.get(j);
18795                if (r.app != app) {
18796                    Log.wtf(TAG, "Found activity " + r + " in proc activity list using " + r.app
18797                            + " instead of expected " + app);
18798                    if (r.app == null || (r.app.uid == app.uid)) {
18799                        // Only fix things up when they look sane
18800                        r.app = app;
18801                    } else {
18802                        continue;
18803                    }
18804                }
18805                if (r.visible) {
18806                    // App has a visible activity; only upgrade adjustment.
18807                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18808                        adj = ProcessList.VISIBLE_APP_ADJ;
18809                        app.adjType = "visible";
18810                    }
18811                    if (procState > PROCESS_STATE_CUR_TOP) {
18812                        procState = PROCESS_STATE_CUR_TOP;
18813                    }
18814                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18815                    app.cached = false;
18816                    app.empty = false;
18817                    foregroundActivities = true;
18818                    if (r.task != null && minLayer > 0) {
18819                        final int layer = r.task.mLayerRank;
18820                        if (layer >= 0 && minLayer > layer) {
18821                            minLayer = layer;
18822                        }
18823                    }
18824                    break;
18825                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
18826                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18827                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18828                        app.adjType = "pausing";
18829                    }
18830                    if (procState > PROCESS_STATE_CUR_TOP) {
18831                        procState = PROCESS_STATE_CUR_TOP;
18832                    }
18833                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18834                    app.cached = false;
18835                    app.empty = false;
18836                    foregroundActivities = true;
18837                } else if (r.state == ActivityState.STOPPING) {
18838                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18839                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18840                        app.adjType = "stopping";
18841                    }
18842                    // For the process state, we will at this point consider the
18843                    // process to be cached.  It will be cached either as an activity
18844                    // or empty depending on whether the activity is finishing.  We do
18845                    // this so that we can treat the process as cached for purposes of
18846                    // memory trimming (determing current memory level, trim command to
18847                    // send to process) since there can be an arbitrary number of stopping
18848                    // processes and they should soon all go into the cached state.
18849                    if (!r.finishing) {
18850                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18851                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18852                        }
18853                    }
18854                    app.cached = false;
18855                    app.empty = false;
18856                    foregroundActivities = true;
18857                } else {
18858                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18859                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18860                        app.adjType = "cch-act";
18861                    }
18862                }
18863            }
18864            if (adj == ProcessList.VISIBLE_APP_ADJ) {
18865                adj += minLayer;
18866            }
18867        }
18868
18869        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
18870                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
18871            if (app.foregroundServices) {
18872                // The user is aware of this app, so make it visible.
18873                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18874                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18875                app.cached = false;
18876                app.adjType = "fg-service";
18877                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18878            } else if (app.forcingToForeground != null) {
18879                // The user is aware of this app, so make it visible.
18880                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18881                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18882                app.cached = false;
18883                app.adjType = "force-fg";
18884                app.adjSource = app.forcingToForeground;
18885                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18886            }
18887        }
18888
18889        if (app == mHeavyWeightProcess) {
18890            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
18891                // We don't want to kill the current heavy-weight process.
18892                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
18893                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18894                app.cached = false;
18895                app.adjType = "heavy";
18896            }
18897            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18898                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
18899            }
18900        }
18901
18902        if (app == mHomeProcess) {
18903            if (adj > ProcessList.HOME_APP_ADJ) {
18904                // This process is hosting what we currently consider to be the
18905                // home app, so we don't want to let it go into the background.
18906                adj = ProcessList.HOME_APP_ADJ;
18907                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18908                app.cached = false;
18909                app.adjType = "home";
18910            }
18911            if (procState > ActivityManager.PROCESS_STATE_HOME) {
18912                procState = ActivityManager.PROCESS_STATE_HOME;
18913            }
18914        }
18915
18916        if (app == mPreviousProcess && app.activities.size() > 0) {
18917            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18918                // This was the previous process that showed UI to the user.
18919                // We want to try to keep it around more aggressively, to give
18920                // a good experience around switching between two apps.
18921                adj = ProcessList.PREVIOUS_APP_ADJ;
18922                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18923                app.cached = false;
18924                app.adjType = "previous";
18925            }
18926            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18927                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18928            }
18929        }
18930
18931        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
18932                + " reason=" + app.adjType);
18933
18934        // By default, we use the computed adjustment.  It may be changed if
18935        // there are applications dependent on our services or providers, but
18936        // this gives us a baseline and makes sure we don't get into an
18937        // infinite recursion.
18938        app.adjSeq = mAdjSeq;
18939        app.curRawAdj = adj;
18940        app.hasStartedServices = false;
18941
18942        if (mBackupTarget != null && app == mBackupTarget.app) {
18943            // If possible we want to avoid killing apps while they're being backed up
18944            if (adj > ProcessList.BACKUP_APP_ADJ) {
18945                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
18946                adj = ProcessList.BACKUP_APP_ADJ;
18947                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18948                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18949                }
18950                app.adjType = "backup";
18951                app.cached = false;
18952            }
18953            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
18954                procState = ActivityManager.PROCESS_STATE_BACKUP;
18955            }
18956        }
18957
18958        boolean mayBeTop = false;
18959
18960        for (int is = app.services.size()-1;
18961                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18962                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18963                        || procState > ActivityManager.PROCESS_STATE_TOP);
18964                is--) {
18965            ServiceRecord s = app.services.valueAt(is);
18966            if (s.startRequested) {
18967                app.hasStartedServices = true;
18968                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
18969                    procState = ActivityManager.PROCESS_STATE_SERVICE;
18970                }
18971                if (app.hasShownUi && app != mHomeProcess) {
18972                    // If this process has shown some UI, let it immediately
18973                    // go to the LRU list because it may be pretty heavy with
18974                    // UI stuff.  We'll tag it with a label just to help
18975                    // debug and understand what is going on.
18976                    if (adj > ProcessList.SERVICE_ADJ) {
18977                        app.adjType = "cch-started-ui-services";
18978                    }
18979                } else {
18980                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18981                        // This service has seen some activity within
18982                        // recent memory, so we will keep its process ahead
18983                        // of the background processes.
18984                        if (adj > ProcessList.SERVICE_ADJ) {
18985                            adj = ProcessList.SERVICE_ADJ;
18986                            app.adjType = "started-services";
18987                            app.cached = false;
18988                        }
18989                    }
18990                    // If we have let the service slide into the background
18991                    // state, still have some text describing what it is doing
18992                    // even though the service no longer has an impact.
18993                    if (adj > ProcessList.SERVICE_ADJ) {
18994                        app.adjType = "cch-started-services";
18995                    }
18996                }
18997            }
18998            for (int conni = s.connections.size()-1;
18999                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19000                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19001                            || procState > ActivityManager.PROCESS_STATE_TOP);
19002                    conni--) {
19003                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
19004                for (int i = 0;
19005                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
19006                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19007                                || procState > ActivityManager.PROCESS_STATE_TOP);
19008                        i++) {
19009                    // XXX should compute this based on the max of
19010                    // all connected clients.
19011                    ConnectionRecord cr = clist.get(i);
19012                    if (cr.binding.client == app) {
19013                        // Binding to ourself is not interesting.
19014                        continue;
19015                    }
19016                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
19017                        ProcessRecord client = cr.binding.client;
19018                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
19019                                TOP_APP, doingAll, now);
19020                        int clientProcState = client.curProcState;
19021                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19022                            // If the other app is cached for any reason, for purposes here
19023                            // we are going to consider it empty.  The specific cached state
19024                            // doesn't propagate except under certain conditions.
19025                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19026                        }
19027                        String adjType = null;
19028                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
19029                            // Not doing bind OOM management, so treat
19030                            // this guy more like a started service.
19031                            if (app.hasShownUi && app != mHomeProcess) {
19032                                // If this process has shown some UI, let it immediately
19033                                // go to the LRU list because it may be pretty heavy with
19034                                // UI stuff.  We'll tag it with a label just to help
19035                                // debug and understand what is going on.
19036                                if (adj > clientAdj) {
19037                                    adjType = "cch-bound-ui-services";
19038                                }
19039                                app.cached = false;
19040                                clientAdj = adj;
19041                                clientProcState = procState;
19042                            } else {
19043                                if (now >= (s.lastActivity
19044                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19045                                    // This service has not seen activity within
19046                                    // recent memory, so allow it to drop to the
19047                                    // LRU list if there is no other reason to keep
19048                                    // it around.  We'll also tag it with a label just
19049                                    // to help debug and undertand what is going on.
19050                                    if (adj > clientAdj) {
19051                                        adjType = "cch-bound-services";
19052                                    }
19053                                    clientAdj = adj;
19054                                }
19055                            }
19056                        }
19057                        if (adj > clientAdj) {
19058                            // If this process has recently shown UI, and
19059                            // the process that is binding to it is less
19060                            // important than being visible, then we don't
19061                            // care about the binding as much as we care
19062                            // about letting this process get into the LRU
19063                            // list to be killed and restarted if needed for
19064                            // memory.
19065                            if (app.hasShownUi && app != mHomeProcess
19066                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19067                                adjType = "cch-bound-ui-services";
19068                            } else {
19069                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
19070                                        |Context.BIND_IMPORTANT)) != 0) {
19071                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
19072                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
19073                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
19074                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
19075                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19076                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19077                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
19078                                    adj = clientAdj;
19079                                } else {
19080                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19081                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
19082                                    }
19083                                }
19084                                if (!client.cached) {
19085                                    app.cached = false;
19086                                }
19087                                adjType = "service";
19088                            }
19089                        }
19090                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19091                            // This will treat important bound services identically to
19092                            // the top app, which may behave differently than generic
19093                            // foreground work.
19094                            if (client.curSchedGroup > schedGroup) {
19095                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19096                                    schedGroup = client.curSchedGroup;
19097                                } else {
19098                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19099                                }
19100                            }
19101                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19102                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19103                                    // Special handling of clients who are in the top state.
19104                                    // We *may* want to consider this process to be in the
19105                                    // top state as well, but only if there is not another
19106                                    // reason for it to be running.  Being on the top is a
19107                                    // special state, meaning you are specifically running
19108                                    // for the current top app.  If the process is already
19109                                    // running in the background for some other reason, it
19110                                    // is more important to continue considering it to be
19111                                    // in the background state.
19112                                    mayBeTop = true;
19113                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19114                                } else {
19115                                    // Special handling for above-top states (persistent
19116                                    // processes).  These should not bring the current process
19117                                    // into the top state, since they are not on top.  Instead
19118                                    // give them the best state after that.
19119                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
19120                                        clientProcState =
19121                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19122                                    } else if (mWakefulness
19123                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
19124                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
19125                                                    != 0) {
19126                                        clientProcState =
19127                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19128                                    } else {
19129                                        clientProcState =
19130                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19131                                    }
19132                                }
19133                            }
19134                        } else {
19135                            if (clientProcState <
19136                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19137                                clientProcState =
19138                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19139                            }
19140                        }
19141                        if (procState > clientProcState) {
19142                            procState = clientProcState;
19143                        }
19144                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19145                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
19146                            app.pendingUiClean = true;
19147                        }
19148                        if (adjType != null) {
19149                            app.adjType = adjType;
19150                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19151                                    .REASON_SERVICE_IN_USE;
19152                            app.adjSource = cr.binding.client;
19153                            app.adjSourceProcState = clientProcState;
19154                            app.adjTarget = s.name;
19155                        }
19156                    }
19157                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
19158                        app.treatLikeActivity = true;
19159                    }
19160                    final ActivityRecord a = cr.activity;
19161                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
19162                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19163                            (a.visible || a.state == ActivityState.RESUMED ||
19164                             a.state == ActivityState.PAUSING)) {
19165                            adj = ProcessList.FOREGROUND_APP_ADJ;
19166                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19167                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19168                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19169                                } else {
19170                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19171                                }
19172                            }
19173                            app.cached = false;
19174                            app.adjType = "service";
19175                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19176                                    .REASON_SERVICE_IN_USE;
19177                            app.adjSource = a;
19178                            app.adjSourceProcState = procState;
19179                            app.adjTarget = s.name;
19180                        }
19181                    }
19182                }
19183            }
19184        }
19185
19186        for (int provi = app.pubProviders.size()-1;
19187                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19188                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19189                        || procState > ActivityManager.PROCESS_STATE_TOP);
19190                provi--) {
19191            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19192            for (int i = cpr.connections.size()-1;
19193                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19194                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19195                            || procState > ActivityManager.PROCESS_STATE_TOP);
19196                    i--) {
19197                ContentProviderConnection conn = cpr.connections.get(i);
19198                ProcessRecord client = conn.client;
19199                if (client == app) {
19200                    // Being our own client is not interesting.
19201                    continue;
19202                }
19203                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19204                int clientProcState = client.curProcState;
19205                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19206                    // If the other app is cached for any reason, for purposes here
19207                    // we are going to consider it empty.
19208                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19209                }
19210                if (adj > clientAdj) {
19211                    if (app.hasShownUi && app != mHomeProcess
19212                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19213                        app.adjType = "cch-ui-provider";
19214                    } else {
19215                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19216                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19217                        app.adjType = "provider";
19218                    }
19219                    app.cached &= client.cached;
19220                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19221                            .REASON_PROVIDER_IN_USE;
19222                    app.adjSource = client;
19223                    app.adjSourceProcState = clientProcState;
19224                    app.adjTarget = cpr.name;
19225                }
19226                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19227                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19228                        // Special handling of clients who are in the top state.
19229                        // We *may* want to consider this process to be in the
19230                        // top state as well, but only if there is not another
19231                        // reason for it to be running.  Being on the top is a
19232                        // special state, meaning you are specifically running
19233                        // for the current top app.  If the process is already
19234                        // running in the background for some other reason, it
19235                        // is more important to continue considering it to be
19236                        // in the background state.
19237                        mayBeTop = true;
19238                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19239                    } else {
19240                        // Special handling for above-top states (persistent
19241                        // processes).  These should not bring the current process
19242                        // into the top state, since they are not on top.  Instead
19243                        // give them the best state after that.
19244                        clientProcState =
19245                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19246                    }
19247                }
19248                if (procState > clientProcState) {
19249                    procState = clientProcState;
19250                }
19251                if (client.curSchedGroup > schedGroup) {
19252                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19253                }
19254            }
19255            // If the provider has external (non-framework) process
19256            // dependencies, ensure that its adjustment is at least
19257            // FOREGROUND_APP_ADJ.
19258            if (cpr.hasExternalProcessHandles()) {
19259                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19260                    adj = ProcessList.FOREGROUND_APP_ADJ;
19261                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19262                    app.cached = false;
19263                    app.adjType = "provider";
19264                    app.adjTarget = cpr.name;
19265                }
19266                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19267                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19268                }
19269            }
19270        }
19271
19272        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19273            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19274                adj = ProcessList.PREVIOUS_APP_ADJ;
19275                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19276                app.cached = false;
19277                app.adjType = "provider";
19278            }
19279            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19280                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19281            }
19282        }
19283
19284        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19285            // A client of one of our services or providers is in the top state.  We
19286            // *may* want to be in the top state, but not if we are already running in
19287            // the background for some other reason.  For the decision here, we are going
19288            // to pick out a few specific states that we want to remain in when a client
19289            // is top (states that tend to be longer-term) and otherwise allow it to go
19290            // to the top state.
19291            switch (procState) {
19292                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19293                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19294                case ActivityManager.PROCESS_STATE_SERVICE:
19295                    // These all are longer-term states, so pull them up to the top
19296                    // of the background states, but not all the way to the top state.
19297                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19298                    break;
19299                default:
19300                    // Otherwise, top is a better choice, so take it.
19301                    procState = ActivityManager.PROCESS_STATE_TOP;
19302                    break;
19303            }
19304        }
19305
19306        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19307            if (app.hasClientActivities) {
19308                // This is a cached process, but with client activities.  Mark it so.
19309                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19310                app.adjType = "cch-client-act";
19311            } else if (app.treatLikeActivity) {
19312                // This is a cached process, but somebody wants us to treat it like it has
19313                // an activity, okay!
19314                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19315                app.adjType = "cch-as-act";
19316            }
19317        }
19318
19319        if (adj == ProcessList.SERVICE_ADJ) {
19320            if (doingAll) {
19321                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19322                mNewNumServiceProcs++;
19323                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19324                if (!app.serviceb) {
19325                    // This service isn't far enough down on the LRU list to
19326                    // normally be a B service, but if we are low on RAM and it
19327                    // is large we want to force it down since we would prefer to
19328                    // keep launcher over it.
19329                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19330                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19331                        app.serviceHighRam = true;
19332                        app.serviceb = true;
19333                        //Slog.i(TAG, "ADJ " + app + " high ram!");
19334                    } else {
19335                        mNewNumAServiceProcs++;
19336                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
19337                    }
19338                } else {
19339                    app.serviceHighRam = false;
19340                }
19341            }
19342            if (app.serviceb) {
19343                adj = ProcessList.SERVICE_B_ADJ;
19344            }
19345        }
19346
19347        app.curRawAdj = adj;
19348
19349        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19350        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19351        if (adj > app.maxAdj) {
19352            adj = app.maxAdj;
19353            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19354                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19355            }
19356        }
19357
19358        // Do final modification to adj.  Everything we do between here and applying
19359        // the final setAdj must be done in this function, because we will also use
19360        // it when computing the final cached adj later.  Note that we don't need to
19361        // worry about this for max adj above, since max adj will always be used to
19362        // keep it out of the cached vaues.
19363        app.curAdj = app.modifyRawOomAdj(adj);
19364        app.curSchedGroup = schedGroup;
19365        app.curProcState = procState;
19366        app.foregroundActivities = foregroundActivities;
19367
19368        return app.curRawAdj;
19369    }
19370
19371    /**
19372     * Record new PSS sample for a process.
19373     */
19374    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19375            long now) {
19376        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19377                swapPss * 1024);
19378        proc.lastPssTime = now;
19379        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19380        if (DEBUG_PSS) Slog.d(TAG_PSS,
19381                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19382                + " state=" + ProcessList.makeProcStateString(procState));
19383        if (proc.initialIdlePss == 0) {
19384            proc.initialIdlePss = pss;
19385        }
19386        proc.lastPss = pss;
19387        proc.lastSwapPss = swapPss;
19388        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19389            proc.lastCachedPss = pss;
19390            proc.lastCachedSwapPss = swapPss;
19391        }
19392
19393        final SparseArray<Pair<Long, String>> watchUids
19394                = mMemWatchProcesses.getMap().get(proc.processName);
19395        Long check = null;
19396        if (watchUids != null) {
19397            Pair<Long, String> val = watchUids.get(proc.uid);
19398            if (val == null) {
19399                val = watchUids.get(0);
19400            }
19401            if (val != null) {
19402                check = val.first;
19403            }
19404        }
19405        if (check != null) {
19406            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19407                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19408                if (!isDebuggable) {
19409                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19410                        isDebuggable = true;
19411                    }
19412                }
19413                if (isDebuggable) {
19414                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19415                    final ProcessRecord myProc = proc;
19416                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
19417                    mMemWatchDumpProcName = proc.processName;
19418                    mMemWatchDumpFile = heapdumpFile.toString();
19419                    mMemWatchDumpPid = proc.pid;
19420                    mMemWatchDumpUid = proc.uid;
19421                    BackgroundThread.getHandler().post(new Runnable() {
19422                        @Override
19423                        public void run() {
19424                            revokeUriPermission(ActivityThread.currentActivityThread()
19425                                            .getApplicationThread(),
19426                                    DumpHeapActivity.JAVA_URI,
19427                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
19428                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19429                                    UserHandle.myUserId());
19430                            ParcelFileDescriptor fd = null;
19431                            try {
19432                                heapdumpFile.delete();
19433                                fd = ParcelFileDescriptor.open(heapdumpFile,
19434                                        ParcelFileDescriptor.MODE_CREATE |
19435                                                ParcelFileDescriptor.MODE_TRUNCATE |
19436                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
19437                                                ParcelFileDescriptor.MODE_APPEND);
19438                                IApplicationThread thread = myProc.thread;
19439                                if (thread != null) {
19440                                    try {
19441                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
19442                                                "Requesting dump heap from "
19443                                                + myProc + " to " + heapdumpFile);
19444                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
19445                                    } catch (RemoteException e) {
19446                                    }
19447                                }
19448                            } catch (FileNotFoundException e) {
19449                                e.printStackTrace();
19450                            } finally {
19451                                if (fd != null) {
19452                                    try {
19453                                        fd.close();
19454                                    } catch (IOException e) {
19455                                    }
19456                                }
19457                            }
19458                        }
19459                    });
19460                } else {
19461                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19462                            + ", but debugging not enabled");
19463                }
19464            }
19465        }
19466    }
19467
19468    /**
19469     * Schedule PSS collection of a process.
19470     */
19471    void requestPssLocked(ProcessRecord proc, int procState) {
19472        if (mPendingPssProcesses.contains(proc)) {
19473            return;
19474        }
19475        if (mPendingPssProcesses.size() == 0) {
19476            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19477        }
19478        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19479        proc.pssProcState = procState;
19480        mPendingPssProcesses.add(proc);
19481    }
19482
19483    /**
19484     * Schedule PSS collection of all processes.
19485     */
19486    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19487        if (!always) {
19488            if (now < (mLastFullPssTime +
19489                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19490                return;
19491            }
19492        }
19493        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
19494        mLastFullPssTime = now;
19495        mFullPssPending = true;
19496        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19497        mPendingPssProcesses.clear();
19498        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19499            ProcessRecord app = mLruProcesses.get(i);
19500            if (app.thread == null
19501                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19502                continue;
19503            }
19504            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19505                app.pssProcState = app.setProcState;
19506                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19507                        mTestPssMode, isSleeping(), now);
19508                mPendingPssProcesses.add(app);
19509            }
19510        }
19511        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19512    }
19513
19514    public void setTestPssMode(boolean enabled) {
19515        synchronized (this) {
19516            mTestPssMode = enabled;
19517            if (enabled) {
19518                // Whenever we enable the mode, we want to take a snapshot all of current
19519                // process mem use.
19520                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19521            }
19522        }
19523    }
19524
19525    /**
19526     * Ask a given process to GC right now.
19527     */
19528    final void performAppGcLocked(ProcessRecord app) {
19529        try {
19530            app.lastRequestedGc = SystemClock.uptimeMillis();
19531            if (app.thread != null) {
19532                if (app.reportLowMemory) {
19533                    app.reportLowMemory = false;
19534                    app.thread.scheduleLowMemory();
19535                } else {
19536                    app.thread.processInBackground();
19537                }
19538            }
19539        } catch (Exception e) {
19540            // whatever.
19541        }
19542    }
19543
19544    /**
19545     * Returns true if things are idle enough to perform GCs.
19546     */
19547    private final boolean canGcNowLocked() {
19548        boolean processingBroadcasts = false;
19549        for (BroadcastQueue q : mBroadcastQueues) {
19550            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19551                processingBroadcasts = true;
19552            }
19553        }
19554        return !processingBroadcasts
19555                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
19556    }
19557
19558    /**
19559     * Perform GCs on all processes that are waiting for it, but only
19560     * if things are idle.
19561     */
19562    final void performAppGcsLocked() {
19563        final int N = mProcessesToGc.size();
19564        if (N <= 0) {
19565            return;
19566        }
19567        if (canGcNowLocked()) {
19568            while (mProcessesToGc.size() > 0) {
19569                ProcessRecord proc = mProcessesToGc.remove(0);
19570                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
19571                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
19572                            <= SystemClock.uptimeMillis()) {
19573                        // To avoid spamming the system, we will GC processes one
19574                        // at a time, waiting a few seconds between each.
19575                        performAppGcLocked(proc);
19576                        scheduleAppGcsLocked();
19577                        return;
19578                    } else {
19579                        // It hasn't been long enough since we last GCed this
19580                        // process...  put it in the list to wait for its time.
19581                        addProcessToGcListLocked(proc);
19582                        break;
19583                    }
19584                }
19585            }
19586
19587            scheduleAppGcsLocked();
19588        }
19589    }
19590
19591    /**
19592     * If all looks good, perform GCs on all processes waiting for them.
19593     */
19594    final void performAppGcsIfAppropriateLocked() {
19595        if (canGcNowLocked()) {
19596            performAppGcsLocked();
19597            return;
19598        }
19599        // Still not idle, wait some more.
19600        scheduleAppGcsLocked();
19601    }
19602
19603    /**
19604     * Schedule the execution of all pending app GCs.
19605     */
19606    final void scheduleAppGcsLocked() {
19607        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
19608
19609        if (mProcessesToGc.size() > 0) {
19610            // Schedule a GC for the time to the next process.
19611            ProcessRecord proc = mProcessesToGc.get(0);
19612            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
19613
19614            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
19615            long now = SystemClock.uptimeMillis();
19616            if (when < (now+GC_TIMEOUT)) {
19617                when = now + GC_TIMEOUT;
19618            }
19619            mHandler.sendMessageAtTime(msg, when);
19620        }
19621    }
19622
19623    /**
19624     * Add a process to the array of processes waiting to be GCed.  Keeps the
19625     * list in sorted order by the last GC time.  The process can't already be
19626     * on the list.
19627     */
19628    final void addProcessToGcListLocked(ProcessRecord proc) {
19629        boolean added = false;
19630        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
19631            if (mProcessesToGc.get(i).lastRequestedGc <
19632                    proc.lastRequestedGc) {
19633                added = true;
19634                mProcessesToGc.add(i+1, proc);
19635                break;
19636            }
19637        }
19638        if (!added) {
19639            mProcessesToGc.add(0, proc);
19640        }
19641    }
19642
19643    /**
19644     * Set up to ask a process to GC itself.  This will either do it
19645     * immediately, or put it on the list of processes to gc the next
19646     * time things are idle.
19647     */
19648    final void scheduleAppGcLocked(ProcessRecord app) {
19649        long now = SystemClock.uptimeMillis();
19650        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
19651            return;
19652        }
19653        if (!mProcessesToGc.contains(app)) {
19654            addProcessToGcListLocked(app);
19655            scheduleAppGcsLocked();
19656        }
19657    }
19658
19659    final void checkExcessivePowerUsageLocked(boolean doKills) {
19660        updateCpuStatsNow();
19661
19662        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19663        boolean doWakeKills = doKills;
19664        boolean doCpuKills = doKills;
19665        if (mLastPowerCheckRealtime == 0) {
19666            doWakeKills = false;
19667        }
19668        if (mLastPowerCheckUptime == 0) {
19669            doCpuKills = false;
19670        }
19671        if (stats.isScreenOn()) {
19672            doWakeKills = false;
19673        }
19674        final long curRealtime = SystemClock.elapsedRealtime();
19675        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
19676        final long curUptime = SystemClock.uptimeMillis();
19677        final long uptimeSince = curUptime - mLastPowerCheckUptime;
19678        mLastPowerCheckRealtime = curRealtime;
19679        mLastPowerCheckUptime = curUptime;
19680        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
19681            doWakeKills = false;
19682        }
19683        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
19684            doCpuKills = false;
19685        }
19686        int i = mLruProcesses.size();
19687        while (i > 0) {
19688            i--;
19689            ProcessRecord app = mLruProcesses.get(i);
19690            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19691                long wtime;
19692                synchronized (stats) {
19693                    wtime = stats.getProcessWakeTime(app.info.uid,
19694                            app.pid, curRealtime);
19695                }
19696                long wtimeUsed = wtime - app.lastWakeTime;
19697                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
19698                if (DEBUG_POWER) {
19699                    StringBuilder sb = new StringBuilder(128);
19700                    sb.append("Wake for ");
19701                    app.toShortString(sb);
19702                    sb.append(": over ");
19703                    TimeUtils.formatDuration(realtimeSince, sb);
19704                    sb.append(" used ");
19705                    TimeUtils.formatDuration(wtimeUsed, sb);
19706                    sb.append(" (");
19707                    sb.append((wtimeUsed*100)/realtimeSince);
19708                    sb.append("%)");
19709                    Slog.i(TAG_POWER, sb.toString());
19710                    sb.setLength(0);
19711                    sb.append("CPU for ");
19712                    app.toShortString(sb);
19713                    sb.append(": over ");
19714                    TimeUtils.formatDuration(uptimeSince, sb);
19715                    sb.append(" used ");
19716                    TimeUtils.formatDuration(cputimeUsed, sb);
19717                    sb.append(" (");
19718                    sb.append((cputimeUsed*100)/uptimeSince);
19719                    sb.append("%)");
19720                    Slog.i(TAG_POWER, sb.toString());
19721                }
19722                // If a process has held a wake lock for more
19723                // than 50% of the time during this period,
19724                // that sounds bad.  Kill!
19725                if (doWakeKills && realtimeSince > 0
19726                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
19727                    synchronized (stats) {
19728                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
19729                                realtimeSince, wtimeUsed);
19730                    }
19731                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
19732                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
19733                } else if (doCpuKills && uptimeSince > 0
19734                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
19735                    synchronized (stats) {
19736                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
19737                                uptimeSince, cputimeUsed);
19738                    }
19739                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
19740                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
19741                } else {
19742                    app.lastWakeTime = wtime;
19743                    app.lastCpuTime = app.curCpuTime;
19744                }
19745            }
19746        }
19747    }
19748
19749    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
19750            long nowElapsed) {
19751        boolean success = true;
19752
19753        if (app.curRawAdj != app.setRawAdj) {
19754            app.setRawAdj = app.curRawAdj;
19755        }
19756
19757        int changes = 0;
19758
19759        if (app.curAdj != app.setAdj) {
19760            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
19761            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19762                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
19763                    + app.adjType);
19764            app.setAdj = app.curAdj;
19765        }
19766
19767        if (app.setSchedGroup != app.curSchedGroup) {
19768            app.setSchedGroup = app.curSchedGroup;
19769            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19770                    "Setting sched group of " + app.processName
19771                    + " to " + app.curSchedGroup);
19772            if (app.waitingToKill != null && app.curReceiver == null
19773                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
19774                app.kill(app.waitingToKill, true);
19775                success = false;
19776            } else {
19777                int processGroup;
19778                switch (app.curSchedGroup) {
19779                    case ProcessList.SCHED_GROUP_BACKGROUND:
19780                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
19781                        break;
19782                    case ProcessList.SCHED_GROUP_TOP_APP:
19783                        processGroup = Process.THREAD_GROUP_TOP_APP;
19784                        break;
19785                    default:
19786                        processGroup = Process.THREAD_GROUP_DEFAULT;
19787                        break;
19788                }
19789                if (true) {
19790                    long oldId = Binder.clearCallingIdentity();
19791                    try {
19792                        Process.setProcessGroup(app.pid, processGroup);
19793                    } catch (Exception e) {
19794                        Slog.w(TAG, "Failed setting process group of " + app.pid
19795                                + " to " + app.curSchedGroup);
19796                        e.printStackTrace();
19797                    } finally {
19798                        Binder.restoreCallingIdentity(oldId);
19799                    }
19800                } else {
19801                    if (app.thread != null) {
19802                        try {
19803                            app.thread.setSchedulingGroup(processGroup);
19804                        } catch (RemoteException e) {
19805                        }
19806                    }
19807                }
19808            }
19809        }
19810        if (app.repForegroundActivities != app.foregroundActivities) {
19811            app.repForegroundActivities = app.foregroundActivities;
19812            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
19813        }
19814        if (app.repProcState != app.curProcState) {
19815            app.repProcState = app.curProcState;
19816            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
19817            if (app.thread != null) {
19818                try {
19819                    if (false) {
19820                        //RuntimeException h = new RuntimeException("here");
19821                        Slog.i(TAG, "Sending new process state " + app.repProcState
19822                                + " to " + app /*, h*/);
19823                    }
19824                    app.thread.setProcessState(app.repProcState);
19825                } catch (RemoteException e) {
19826                }
19827            }
19828        }
19829        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
19830                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
19831            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
19832                // Experimental code to more aggressively collect pss while
19833                // running test...  the problem is that this tends to collect
19834                // the data right when a process is transitioning between process
19835                // states, which well tend to give noisy data.
19836                long start = SystemClock.uptimeMillis();
19837                long pss = Debug.getPss(app.pid, mTmpLong, null);
19838                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
19839                mPendingPssProcesses.remove(app);
19840                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
19841                        + " to " + app.curProcState + ": "
19842                        + (SystemClock.uptimeMillis()-start) + "ms");
19843            }
19844            app.lastStateTime = now;
19845            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19846                    mTestPssMode, isSleeping(), now);
19847            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
19848                    + ProcessList.makeProcStateString(app.setProcState) + " to "
19849                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
19850                    + (app.nextPssTime-now) + ": " + app);
19851        } else {
19852            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
19853                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
19854                    mTestPssMode)))) {
19855                requestPssLocked(app, app.setProcState);
19856                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
19857                        mTestPssMode, isSleeping(), now);
19858            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
19859                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
19860        }
19861        if (app.setProcState != app.curProcState) {
19862            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19863                    "Proc state change of " + app.processName
19864                            + " to " + app.curProcState);
19865            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
19866            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
19867            if (setImportant && !curImportant) {
19868                // This app is no longer something we consider important enough to allow to
19869                // use arbitrary amounts of battery power.  Note
19870                // its current wake lock time to later know to kill it if
19871                // it is not behaving well.
19872                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19873                synchronized (stats) {
19874                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
19875                            app.pid, nowElapsed);
19876                }
19877                app.lastCpuTime = app.curCpuTime;
19878
19879            }
19880            // Inform UsageStats of important process state change
19881            // Must be called before updating setProcState
19882            maybeUpdateUsageStatsLocked(app, nowElapsed);
19883
19884            app.setProcState = app.curProcState;
19885            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19886                app.notCachedSinceIdle = false;
19887            }
19888            if (!doingAll) {
19889                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
19890            } else {
19891                app.procStateChanged = true;
19892            }
19893        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
19894                > USAGE_STATS_INTERACTION_INTERVAL) {
19895            // For apps that sit around for a long time in the interactive state, we need
19896            // to report this at least once a day so they don't go idle.
19897            maybeUpdateUsageStatsLocked(app, nowElapsed);
19898        }
19899
19900        if (changes != 0) {
19901            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19902                    "Changes in " + app + ": " + changes);
19903            int i = mPendingProcessChanges.size()-1;
19904            ProcessChangeItem item = null;
19905            while (i >= 0) {
19906                item = mPendingProcessChanges.get(i);
19907                if (item.pid == app.pid) {
19908                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19909                            "Re-using existing item: " + item);
19910                    break;
19911                }
19912                i--;
19913            }
19914            if (i < 0) {
19915                // No existing item in pending changes; need a new one.
19916                final int NA = mAvailProcessChanges.size();
19917                if (NA > 0) {
19918                    item = mAvailProcessChanges.remove(NA-1);
19919                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19920                            "Retrieving available item: " + item);
19921                } else {
19922                    item = new ProcessChangeItem();
19923                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19924                            "Allocating new item: " + item);
19925                }
19926                item.changes = 0;
19927                item.pid = app.pid;
19928                item.uid = app.info.uid;
19929                if (mPendingProcessChanges.size() == 0) {
19930                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19931                            "*** Enqueueing dispatch processes changed!");
19932                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
19933                }
19934                mPendingProcessChanges.add(item);
19935            }
19936            item.changes |= changes;
19937            item.processState = app.repProcState;
19938            item.foregroundActivities = app.repForegroundActivities;
19939            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19940                    "Item " + Integer.toHexString(System.identityHashCode(item))
19941                    + " " + app.toShortString() + ": changes=" + item.changes
19942                    + " procState=" + item.processState
19943                    + " foreground=" + item.foregroundActivities
19944                    + " type=" + app.adjType + " source=" + app.adjSource
19945                    + " target=" + app.adjTarget);
19946        }
19947
19948        return success;
19949    }
19950
19951    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
19952        final UidRecord.ChangeItem pendingChange;
19953        if (uidRec == null || uidRec.pendingChange == null) {
19954            if (mPendingUidChanges.size() == 0) {
19955                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19956                        "*** Enqueueing dispatch uid changed!");
19957                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
19958            }
19959            final int NA = mAvailUidChanges.size();
19960            if (NA > 0) {
19961                pendingChange = mAvailUidChanges.remove(NA-1);
19962                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19963                        "Retrieving available item: " + pendingChange);
19964            } else {
19965                pendingChange = new UidRecord.ChangeItem();
19966                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19967                        "Allocating new item: " + pendingChange);
19968            }
19969            if (uidRec != null) {
19970                uidRec.pendingChange = pendingChange;
19971                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
19972                    // If this uid is going away, and we haven't yet reported it is gone,
19973                    // then do so now.
19974                    change = UidRecord.CHANGE_GONE_IDLE;
19975                }
19976            } else if (uid < 0) {
19977                throw new IllegalArgumentException("No UidRecord or uid");
19978            }
19979            pendingChange.uidRecord = uidRec;
19980            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
19981            mPendingUidChanges.add(pendingChange);
19982        } else {
19983            pendingChange = uidRec.pendingChange;
19984            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
19985                change = UidRecord.CHANGE_GONE_IDLE;
19986            }
19987        }
19988        pendingChange.change = change;
19989        pendingChange.processState = uidRec != null
19990                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
19991    }
19992
19993    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
19994            String authority) {
19995        if (app == null) return;
19996        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19997            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
19998            if (userState == null) return;
19999            final long now = SystemClock.elapsedRealtime();
20000            Long lastReported = userState.mProviderLastReportedFg.get(authority);
20001            if (lastReported == null || lastReported < now - 60 * 1000L) {
20002                mUsageStatsService.reportContentProviderUsage(
20003                        authority, providerPkgName, app.userId);
20004                userState.mProviderLastReportedFg.put(authority, now);
20005            }
20006        }
20007    }
20008
20009    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
20010        if (DEBUG_USAGE_STATS) {
20011            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
20012                    + "] state changes: old = " + app.setProcState + ", new = "
20013                    + app.curProcState);
20014        }
20015        if (mUsageStatsService == null) {
20016            return;
20017        }
20018        boolean isInteraction;
20019        // To avoid some abuse patterns, we are going to be careful about what we consider
20020        // to be an app interaction.  Being the top activity doesn't count while the display
20021        // is sleeping, nor do short foreground services.
20022        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
20023            isInteraction = true;
20024            app.fgInteractionTime = 0;
20025        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
20026            if (app.fgInteractionTime == 0) {
20027                app.fgInteractionTime = nowElapsed;
20028                isInteraction = false;
20029            } else {
20030                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
20031            }
20032        } else {
20033            isInteraction = app.curProcState
20034                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20035            app.fgInteractionTime = 0;
20036        }
20037        if (isInteraction && (!app.reportedInteraction
20038                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
20039            app.interactionEventTime = nowElapsed;
20040            String[] packages = app.getPackageList();
20041            if (packages != null) {
20042                for (int i = 0; i < packages.length; i++) {
20043                    mUsageStatsService.reportEvent(packages[i], app.userId,
20044                            UsageEvents.Event.SYSTEM_INTERACTION);
20045                }
20046            }
20047        }
20048        app.reportedInteraction = isInteraction;
20049        if (!isInteraction) {
20050            app.interactionEventTime = 0;
20051        }
20052    }
20053
20054    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
20055        if (proc.thread != null) {
20056            if (proc.baseProcessTracker != null) {
20057                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
20058            }
20059        }
20060    }
20061
20062    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
20063            ProcessRecord TOP_APP, boolean doingAll, long now) {
20064        if (app.thread == null) {
20065            return false;
20066        }
20067
20068        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
20069
20070        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
20071    }
20072
20073    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
20074            boolean oomAdj) {
20075        if (isForeground != proc.foregroundServices) {
20076            proc.foregroundServices = isForeground;
20077            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
20078                    proc.info.uid);
20079            if (isForeground) {
20080                if (curProcs == null) {
20081                    curProcs = new ArrayList<ProcessRecord>();
20082                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
20083                }
20084                if (!curProcs.contains(proc)) {
20085                    curProcs.add(proc);
20086                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
20087                            proc.info.packageName, proc.info.uid);
20088                }
20089            } else {
20090                if (curProcs != null) {
20091                    if (curProcs.remove(proc)) {
20092                        mBatteryStatsService.noteEvent(
20093                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
20094                                proc.info.packageName, proc.info.uid);
20095                        if (curProcs.size() <= 0) {
20096                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
20097                        }
20098                    }
20099                }
20100            }
20101            if (oomAdj) {
20102                updateOomAdjLocked();
20103            }
20104        }
20105    }
20106
20107    private final ActivityRecord resumedAppLocked() {
20108        ActivityRecord act = mStackSupervisor.resumedAppLocked();
20109        String pkg;
20110        int uid;
20111        if (act != null) {
20112            pkg = act.packageName;
20113            uid = act.info.applicationInfo.uid;
20114        } else {
20115            pkg = null;
20116            uid = -1;
20117        }
20118        // Has the UID or resumed package name changed?
20119        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
20120                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
20121            if (mCurResumedPackage != null) {
20122                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
20123                        mCurResumedPackage, mCurResumedUid);
20124            }
20125            mCurResumedPackage = pkg;
20126            mCurResumedUid = uid;
20127            if (mCurResumedPackage != null) {
20128                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
20129                        mCurResumedPackage, mCurResumedUid);
20130            }
20131        }
20132        return act;
20133    }
20134
20135    final boolean updateOomAdjLocked(ProcessRecord app) {
20136        final ActivityRecord TOP_ACT = resumedAppLocked();
20137        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20138        final boolean wasCached = app.cached;
20139
20140        mAdjSeq++;
20141
20142        // This is the desired cached adjusment we want to tell it to use.
20143        // If our app is currently cached, we know it, and that is it.  Otherwise,
20144        // we don't know it yet, and it needs to now be cached we will then
20145        // need to do a complete oom adj.
20146        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
20147                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
20148        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
20149                SystemClock.uptimeMillis());
20150        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
20151            // Changed to/from cached state, so apps after it in the LRU
20152            // list may also be changed.
20153            updateOomAdjLocked();
20154        }
20155        return success;
20156    }
20157
20158    final void updateOomAdjLocked() {
20159        final ActivityRecord TOP_ACT = resumedAppLocked();
20160        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20161        final long now = SystemClock.uptimeMillis();
20162        final long nowElapsed = SystemClock.elapsedRealtime();
20163        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20164        final int N = mLruProcesses.size();
20165
20166        if (false) {
20167            RuntimeException e = new RuntimeException();
20168            e.fillInStackTrace();
20169            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20170        }
20171
20172        // Reset state in all uid records.
20173        for (int i=mActiveUids.size()-1; i>=0; i--) {
20174            final UidRecord uidRec = mActiveUids.valueAt(i);
20175            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20176                    "Starting update of " + uidRec);
20177            uidRec.reset();
20178        }
20179
20180        mStackSupervisor.rankTaskLayersIfNeeded();
20181
20182        mAdjSeq++;
20183        mNewNumServiceProcs = 0;
20184        mNewNumAServiceProcs = 0;
20185
20186        final int emptyProcessLimit;
20187        final int cachedProcessLimit;
20188        if (mProcessLimit <= 0) {
20189            emptyProcessLimit = cachedProcessLimit = 0;
20190        } else if (mProcessLimit == 1) {
20191            emptyProcessLimit = 1;
20192            cachedProcessLimit = 0;
20193        } else {
20194            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20195            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20196        }
20197
20198        // Let's determine how many processes we have running vs.
20199        // how many slots we have for background processes; we may want
20200        // to put multiple processes in a slot of there are enough of
20201        // them.
20202        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20203                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20204        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20205        if (numEmptyProcs > cachedProcessLimit) {
20206            // If there are more empty processes than our limit on cached
20207            // processes, then use the cached process limit for the factor.
20208            // This ensures that the really old empty processes get pushed
20209            // down to the bottom, so if we are running low on memory we will
20210            // have a better chance at keeping around more cached processes
20211            // instead of a gazillion empty processes.
20212            numEmptyProcs = cachedProcessLimit;
20213        }
20214        int emptyFactor = numEmptyProcs/numSlots;
20215        if (emptyFactor < 1) emptyFactor = 1;
20216        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20217        if (cachedFactor < 1) cachedFactor = 1;
20218        int stepCached = 0;
20219        int stepEmpty = 0;
20220        int numCached = 0;
20221        int numEmpty = 0;
20222        int numTrimming = 0;
20223
20224        mNumNonCachedProcs = 0;
20225        mNumCachedHiddenProcs = 0;
20226
20227        // First update the OOM adjustment for each of the
20228        // application processes based on their current state.
20229        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20230        int nextCachedAdj = curCachedAdj+1;
20231        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20232        int nextEmptyAdj = curEmptyAdj+2;
20233        for (int i=N-1; i>=0; i--) {
20234            ProcessRecord app = mLruProcesses.get(i);
20235            if (!app.killedByAm && app.thread != null) {
20236                app.procStateChanged = false;
20237                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20238
20239                // If we haven't yet assigned the final cached adj
20240                // to the process, do that now.
20241                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20242                    switch (app.curProcState) {
20243                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20244                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20245                            // This process is a cached process holding activities...
20246                            // assign it the next cached value for that type, and then
20247                            // step that cached level.
20248                            app.curRawAdj = curCachedAdj;
20249                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20250                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20251                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20252                                    + ")");
20253                            if (curCachedAdj != nextCachedAdj) {
20254                                stepCached++;
20255                                if (stepCached >= cachedFactor) {
20256                                    stepCached = 0;
20257                                    curCachedAdj = nextCachedAdj;
20258                                    nextCachedAdj += 2;
20259                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20260                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20261                                    }
20262                                }
20263                            }
20264                            break;
20265                        default:
20266                            // For everything else, assign next empty cached process
20267                            // level and bump that up.  Note that this means that
20268                            // long-running services that have dropped down to the
20269                            // cached level will be treated as empty (since their process
20270                            // state is still as a service), which is what we want.
20271                            app.curRawAdj = curEmptyAdj;
20272                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20273                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20274                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20275                                    + ")");
20276                            if (curEmptyAdj != nextEmptyAdj) {
20277                                stepEmpty++;
20278                                if (stepEmpty >= emptyFactor) {
20279                                    stepEmpty = 0;
20280                                    curEmptyAdj = nextEmptyAdj;
20281                                    nextEmptyAdj += 2;
20282                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20283                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20284                                    }
20285                                }
20286                            }
20287                            break;
20288                    }
20289                }
20290
20291                applyOomAdjLocked(app, true, now, nowElapsed);
20292
20293                // Count the number of process types.
20294                switch (app.curProcState) {
20295                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20296                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20297                        mNumCachedHiddenProcs++;
20298                        numCached++;
20299                        if (numCached > cachedProcessLimit) {
20300                            app.kill("cached #" + numCached, true);
20301                        }
20302                        break;
20303                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20304                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20305                                && app.lastActivityTime < oldTime) {
20306                            app.kill("empty for "
20307                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20308                                    / 1000) + "s", true);
20309                        } else {
20310                            numEmpty++;
20311                            if (numEmpty > emptyProcessLimit) {
20312                                app.kill("empty #" + numEmpty, true);
20313                            }
20314                        }
20315                        break;
20316                    default:
20317                        mNumNonCachedProcs++;
20318                        break;
20319                }
20320
20321                if (app.isolated && app.services.size() <= 0) {
20322                    // If this is an isolated process, and there are no
20323                    // services running in it, then the process is no longer
20324                    // needed.  We agressively kill these because we can by
20325                    // definition not re-use the same process again, and it is
20326                    // good to avoid having whatever code was running in them
20327                    // left sitting around after no longer needed.
20328                    app.kill("isolated not needed", true);
20329                } else {
20330                    // Keeping this process, update its uid.
20331                    final UidRecord uidRec = app.uidRecord;
20332                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
20333                        uidRec.curProcState = app.curProcState;
20334                    }
20335                }
20336
20337                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20338                        && !app.killedByAm) {
20339                    numTrimming++;
20340                }
20341            }
20342        }
20343
20344        mNumServiceProcs = mNewNumServiceProcs;
20345
20346        // Now determine the memory trimming level of background processes.
20347        // Unfortunately we need to start at the back of the list to do this
20348        // properly.  We only do this if the number of background apps we
20349        // are managing to keep around is less than half the maximum we desire;
20350        // if we are keeping a good number around, we'll let them use whatever
20351        // memory they want.
20352        final int numCachedAndEmpty = numCached + numEmpty;
20353        int memFactor;
20354        if (numCached <= ProcessList.TRIM_CACHED_APPS
20355                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
20356            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
20357                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
20358            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
20359                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
20360            } else {
20361                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
20362            }
20363        } else {
20364            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
20365        }
20366        // We always allow the memory level to go up (better).  We only allow it to go
20367        // down if we are in a state where that is allowed, *and* the total number of processes
20368        // has gone down since last time.
20369        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
20370                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
20371                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
20372        if (memFactor > mLastMemoryLevel) {
20373            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
20374                memFactor = mLastMemoryLevel;
20375                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
20376            }
20377        }
20378        if (memFactor != mLastMemoryLevel) {
20379            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
20380        }
20381        mLastMemoryLevel = memFactor;
20382        mLastNumProcesses = mLruProcesses.size();
20383        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
20384        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
20385        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
20386            if (mLowRamStartTime == 0) {
20387                mLowRamStartTime = now;
20388            }
20389            int step = 0;
20390            int fgTrimLevel;
20391            switch (memFactor) {
20392                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20393                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20394                    break;
20395                case ProcessStats.ADJ_MEM_FACTOR_LOW:
20396                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20397                    break;
20398                default:
20399                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20400                    break;
20401            }
20402            int factor = numTrimming/3;
20403            int minFactor = 2;
20404            if (mHomeProcess != null) minFactor++;
20405            if (mPreviousProcess != null) minFactor++;
20406            if (factor < minFactor) factor = minFactor;
20407            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20408            for (int i=N-1; i>=0; i--) {
20409                ProcessRecord app = mLruProcesses.get(i);
20410                if (allChanged || app.procStateChanged) {
20411                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20412                    app.procStateChanged = false;
20413                }
20414                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20415                        && !app.killedByAm) {
20416                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
20417                        try {
20418                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20419                                    "Trimming memory of " + app.processName + " to " + curLevel);
20420                            app.thread.scheduleTrimMemory(curLevel);
20421                        } catch (RemoteException e) {
20422                        }
20423                        if (false) {
20424                            // For now we won't do this; our memory trimming seems
20425                            // to be good enough at this point that destroying
20426                            // activities causes more harm than good.
20427                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20428                                    && app != mHomeProcess && app != mPreviousProcess) {
20429                                // Need to do this on its own message because the stack may not
20430                                // be in a consistent state at this point.
20431                                // For these apps we will also finish their activities
20432                                // to help them free memory.
20433                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20434                            }
20435                        }
20436                    }
20437                    app.trimMemoryLevel = curLevel;
20438                    step++;
20439                    if (step >= factor) {
20440                        step = 0;
20441                        switch (curLevel) {
20442                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20443                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20444                                break;
20445                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20446                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20447                                break;
20448                        }
20449                    }
20450                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20451                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20452                            && app.thread != null) {
20453                        try {
20454                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20455                                    "Trimming memory of heavy-weight " + app.processName
20456                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20457                            app.thread.scheduleTrimMemory(
20458                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20459                        } catch (RemoteException e) {
20460                        }
20461                    }
20462                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20463                } else {
20464                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20465                            || app.systemNoUi) && app.pendingUiClean) {
20466                        // If this application is now in the background and it
20467                        // had done UI, then give it the special trim level to
20468                        // have it free UI resources.
20469                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20470                        if (app.trimMemoryLevel < level && app.thread != null) {
20471                            try {
20472                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20473                                        "Trimming memory of bg-ui " + app.processName
20474                                        + " to " + level);
20475                                app.thread.scheduleTrimMemory(level);
20476                            } catch (RemoteException e) {
20477                            }
20478                        }
20479                        app.pendingUiClean = false;
20480                    }
20481                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20482                        try {
20483                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20484                                    "Trimming memory of fg " + app.processName
20485                                    + " to " + fgTrimLevel);
20486                            app.thread.scheduleTrimMemory(fgTrimLevel);
20487                        } catch (RemoteException e) {
20488                        }
20489                    }
20490                    app.trimMemoryLevel = fgTrimLevel;
20491                }
20492            }
20493        } else {
20494            if (mLowRamStartTime != 0) {
20495                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20496                mLowRamStartTime = 0;
20497            }
20498            for (int i=N-1; i>=0; i--) {
20499                ProcessRecord app = mLruProcesses.get(i);
20500                if (allChanged || app.procStateChanged) {
20501                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20502                    app.procStateChanged = false;
20503                }
20504                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20505                        || app.systemNoUi) && app.pendingUiClean) {
20506                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20507                            && app.thread != null) {
20508                        try {
20509                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20510                                    "Trimming memory of ui hidden " + app.processName
20511                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20512                            app.thread.scheduleTrimMemory(
20513                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20514                        } catch (RemoteException e) {
20515                        }
20516                    }
20517                    app.pendingUiClean = false;
20518                }
20519                app.trimMemoryLevel = 0;
20520            }
20521        }
20522
20523        if (mAlwaysFinishActivities) {
20524            // Need to do this on its own message because the stack may not
20525            // be in a consistent state at this point.
20526            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20527        }
20528
20529        if (allChanged) {
20530            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
20531        }
20532
20533        // Update from any uid changes.
20534        for (int i=mActiveUids.size()-1; i>=0; i--) {
20535            final UidRecord uidRec = mActiveUids.valueAt(i);
20536            int uidChange = UidRecord.CHANGE_PROCSTATE;
20537            if (uidRec.setProcState != uidRec.curProcState) {
20538                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20539                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
20540                        + " to " + uidRec.curProcState);
20541                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
20542                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
20543                        uidRec.lastBackgroundTime = nowElapsed;
20544                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
20545                            // Note: the background settle time is in elapsed realtime, while
20546                            // the handler time base is uptime.  All this means is that we may
20547                            // stop background uids later than we had intended, but that only
20548                            // happens because the device was sleeping so we are okay anyway.
20549                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
20550                        }
20551                    }
20552                } else {
20553                    if (uidRec.idle) {
20554                        uidChange = UidRecord.CHANGE_ACTIVE;
20555                        uidRec.idle = false;
20556                    }
20557                    uidRec.lastBackgroundTime = 0;
20558                }
20559                uidRec.setProcState = uidRec.curProcState;
20560                enqueueUidChangeLocked(uidRec, -1, uidChange);
20561                noteUidProcessState(uidRec.uid, uidRec.curProcState);
20562            }
20563        }
20564
20565        if (mProcessStats.shouldWriteNowLocked(now)) {
20566            mHandler.post(new Runnable() {
20567                @Override public void run() {
20568                    synchronized (ActivityManagerService.this) {
20569                        mProcessStats.writeStateAsyncLocked();
20570                    }
20571                }
20572            });
20573        }
20574
20575        if (DEBUG_OOM_ADJ) {
20576            final long duration = SystemClock.uptimeMillis() - now;
20577            if (false) {
20578                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
20579                        new RuntimeException("here").fillInStackTrace());
20580            } else {
20581                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
20582            }
20583        }
20584    }
20585
20586    final void idleUids() {
20587        synchronized (this) {
20588            final long nowElapsed = SystemClock.elapsedRealtime();
20589            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
20590            long nextTime = 0;
20591            for (int i=mActiveUids.size()-1; i>=0; i--) {
20592                final UidRecord uidRec = mActiveUids.valueAt(i);
20593                final long bgTime = uidRec.lastBackgroundTime;
20594                if (bgTime > 0 && !uidRec.idle) {
20595                    if (bgTime <= maxBgTime) {
20596                        uidRec.idle = true;
20597                        doStopUidLocked(uidRec.uid, uidRec);
20598                    } else {
20599                        if (nextTime == 0 || nextTime > bgTime) {
20600                            nextTime = bgTime;
20601                        }
20602                    }
20603                }
20604            }
20605            if (nextTime > 0) {
20606                mHandler.removeMessages(IDLE_UIDS_MSG);
20607                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
20608                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
20609            }
20610        }
20611    }
20612
20613    final void runInBackgroundDisabled(int uid) {
20614        synchronized (this) {
20615            UidRecord uidRec = mActiveUids.get(uid);
20616            if (uidRec != null) {
20617                // This uid is actually running...  should it be considered background now?
20618                if (uidRec.idle) {
20619                    doStopUidLocked(uidRec.uid, uidRec);
20620                }
20621            } else {
20622                // This uid isn't actually running...  still send a report about it being "stopped".
20623                doStopUidLocked(uid, null);
20624            }
20625        }
20626    }
20627
20628    final void doStopUidLocked(int uid, final UidRecord uidRec) {
20629        mServices.stopInBackgroundLocked(uid);
20630        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
20631    }
20632
20633    final void trimApplications() {
20634        synchronized (this) {
20635            int i;
20636
20637            // First remove any unused application processes whose package
20638            // has been removed.
20639            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
20640                final ProcessRecord app = mRemovedProcesses.get(i);
20641                if (app.activities.size() == 0
20642                        && app.curReceiver == null && app.services.size() == 0) {
20643                    Slog.i(
20644                        TAG, "Exiting empty application process "
20645                        + app.toShortString() + " ("
20646                        + (app.thread != null ? app.thread.asBinder() : null)
20647                        + ")\n");
20648                    if (app.pid > 0 && app.pid != MY_PID) {
20649                        app.kill("empty", false);
20650                    } else {
20651                        try {
20652                            app.thread.scheduleExit();
20653                        } catch (Exception e) {
20654                            // Ignore exceptions.
20655                        }
20656                    }
20657                    cleanUpApplicationRecordLocked(app, false, true, -1);
20658                    mRemovedProcesses.remove(i);
20659
20660                    if (app.persistent) {
20661                        addAppLocked(app.info, false, null /* ABI override */);
20662                    }
20663                }
20664            }
20665
20666            // Now update the oom adj for all processes.
20667            updateOomAdjLocked();
20668        }
20669    }
20670
20671    /** This method sends the specified signal to each of the persistent apps */
20672    public void signalPersistentProcesses(int sig) throws RemoteException {
20673        if (sig != Process.SIGNAL_USR1) {
20674            throw new SecurityException("Only SIGNAL_USR1 is allowed");
20675        }
20676
20677        synchronized (this) {
20678            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
20679                    != PackageManager.PERMISSION_GRANTED) {
20680                throw new SecurityException("Requires permission "
20681                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
20682            }
20683
20684            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
20685                ProcessRecord r = mLruProcesses.get(i);
20686                if (r.thread != null && r.persistent) {
20687                    Process.sendSignal(r.pid, sig);
20688                }
20689            }
20690        }
20691    }
20692
20693    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
20694        if (proc == null || proc == mProfileProc) {
20695            proc = mProfileProc;
20696            profileType = mProfileType;
20697            clearProfilerLocked();
20698        }
20699        if (proc == null) {
20700            return;
20701        }
20702        try {
20703            proc.thread.profilerControl(false, null, profileType);
20704        } catch (RemoteException e) {
20705            throw new IllegalStateException("Process disappeared");
20706        }
20707    }
20708
20709    private void clearProfilerLocked() {
20710        if (mProfileFd != null) {
20711            try {
20712                mProfileFd.close();
20713            } catch (IOException e) {
20714            }
20715        }
20716        mProfileApp = null;
20717        mProfileProc = null;
20718        mProfileFile = null;
20719        mProfileType = 0;
20720        mAutoStopProfiler = false;
20721        mSamplingInterval = 0;
20722    }
20723
20724    public boolean profileControl(String process, int userId, boolean start,
20725            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
20726
20727        try {
20728            synchronized (this) {
20729                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20730                // its own permission.
20731                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20732                        != PackageManager.PERMISSION_GRANTED) {
20733                    throw new SecurityException("Requires permission "
20734                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20735                }
20736
20737                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
20738                    throw new IllegalArgumentException("null profile info or fd");
20739                }
20740
20741                ProcessRecord proc = null;
20742                if (process != null) {
20743                    proc = findProcessLocked(process, userId, "profileControl");
20744                }
20745
20746                if (start && (proc == null || proc.thread == null)) {
20747                    throw new IllegalArgumentException("Unknown process: " + process);
20748                }
20749
20750                if (start) {
20751                    stopProfilerLocked(null, 0);
20752                    setProfileApp(proc.info, proc.processName, profilerInfo);
20753                    mProfileProc = proc;
20754                    mProfileType = profileType;
20755                    ParcelFileDescriptor fd = profilerInfo.profileFd;
20756                    try {
20757                        fd = fd.dup();
20758                    } catch (IOException e) {
20759                        fd = null;
20760                    }
20761                    profilerInfo.profileFd = fd;
20762                    proc.thread.profilerControl(start, profilerInfo, profileType);
20763                    fd = null;
20764                    mProfileFd = null;
20765                } else {
20766                    stopProfilerLocked(proc, profileType);
20767                    if (profilerInfo != null && profilerInfo.profileFd != null) {
20768                        try {
20769                            profilerInfo.profileFd.close();
20770                        } catch (IOException e) {
20771                        }
20772                    }
20773                }
20774
20775                return true;
20776            }
20777        } catch (RemoteException e) {
20778            throw new IllegalStateException("Process disappeared");
20779        } finally {
20780            if (profilerInfo != null && profilerInfo.profileFd != null) {
20781                try {
20782                    profilerInfo.profileFd.close();
20783                } catch (IOException e) {
20784                }
20785            }
20786        }
20787    }
20788
20789    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
20790        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
20791                userId, true, ALLOW_FULL_ONLY, callName, null);
20792        ProcessRecord proc = null;
20793        try {
20794            int pid = Integer.parseInt(process);
20795            synchronized (mPidsSelfLocked) {
20796                proc = mPidsSelfLocked.get(pid);
20797            }
20798        } catch (NumberFormatException e) {
20799        }
20800
20801        if (proc == null) {
20802            ArrayMap<String, SparseArray<ProcessRecord>> all
20803                    = mProcessNames.getMap();
20804            SparseArray<ProcessRecord> procs = all.get(process);
20805            if (procs != null && procs.size() > 0) {
20806                proc = procs.valueAt(0);
20807                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
20808                    for (int i=1; i<procs.size(); i++) {
20809                        ProcessRecord thisProc = procs.valueAt(i);
20810                        if (thisProc.userId == userId) {
20811                            proc = thisProc;
20812                            break;
20813                        }
20814                    }
20815                }
20816            }
20817        }
20818
20819        return proc;
20820    }
20821
20822    public boolean dumpHeap(String process, int userId, boolean managed,
20823            String path, ParcelFileDescriptor fd) throws RemoteException {
20824
20825        try {
20826            synchronized (this) {
20827                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20828                // its own permission (same as profileControl).
20829                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20830                        != PackageManager.PERMISSION_GRANTED) {
20831                    throw new SecurityException("Requires permission "
20832                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20833                }
20834
20835                if (fd == null) {
20836                    throw new IllegalArgumentException("null fd");
20837                }
20838
20839                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
20840                if (proc == null || proc.thread == null) {
20841                    throw new IllegalArgumentException("Unknown process: " + process);
20842                }
20843
20844                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20845                if (!isDebuggable) {
20846                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20847                        throw new SecurityException("Process not debuggable: " + proc);
20848                    }
20849                }
20850
20851                proc.thread.dumpHeap(managed, path, fd);
20852                fd = null;
20853                return true;
20854            }
20855        } catch (RemoteException e) {
20856            throw new IllegalStateException("Process disappeared");
20857        } finally {
20858            if (fd != null) {
20859                try {
20860                    fd.close();
20861                } catch (IOException e) {
20862                }
20863            }
20864        }
20865    }
20866
20867    @Override
20868    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
20869            String reportPackage) {
20870        if (processName != null) {
20871            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
20872                    "setDumpHeapDebugLimit()");
20873        } else {
20874            synchronized (mPidsSelfLocked) {
20875                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
20876                if (proc == null) {
20877                    throw new SecurityException("No process found for calling pid "
20878                            + Binder.getCallingPid());
20879                }
20880                if (!Build.IS_DEBUGGABLE
20881                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20882                    throw new SecurityException("Not running a debuggable build");
20883                }
20884                processName = proc.processName;
20885                uid = proc.uid;
20886                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
20887                    throw new SecurityException("Package " + reportPackage + " is not running in "
20888                            + proc);
20889                }
20890            }
20891        }
20892        synchronized (this) {
20893            if (maxMemSize > 0) {
20894                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
20895            } else {
20896                if (uid != 0) {
20897                    mMemWatchProcesses.remove(processName, uid);
20898                } else {
20899                    mMemWatchProcesses.getMap().remove(processName);
20900                }
20901            }
20902        }
20903    }
20904
20905    @Override
20906    public void dumpHeapFinished(String path) {
20907        synchronized (this) {
20908            if (Binder.getCallingPid() != mMemWatchDumpPid) {
20909                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
20910                        + " does not match last pid " + mMemWatchDumpPid);
20911                return;
20912            }
20913            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
20914                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
20915                        + " does not match last path " + mMemWatchDumpFile);
20916                return;
20917            }
20918            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
20919            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
20920        }
20921    }
20922
20923    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
20924    public void monitor() {
20925        synchronized (this) { }
20926    }
20927
20928    void onCoreSettingsChange(Bundle settings) {
20929        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20930            ProcessRecord processRecord = mLruProcesses.get(i);
20931            try {
20932                if (processRecord.thread != null) {
20933                    processRecord.thread.setCoreSettings(settings);
20934                }
20935            } catch (RemoteException re) {
20936                /* ignore */
20937            }
20938        }
20939    }
20940
20941    // Multi-user methods
20942
20943    /**
20944     * Start user, if its not already running, but don't bring it to foreground.
20945     */
20946    @Override
20947    public boolean startUserInBackground(final int userId) {
20948        return mUserController.startUser(userId, /* foreground */ false);
20949    }
20950
20951    @Override
20952    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
20953        return mUserController.unlockUser(userId, token, secret, listener);
20954    }
20955
20956    @Override
20957    public boolean switchUser(final int targetUserId) {
20958        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
20959        UserInfo currentUserInfo;
20960        UserInfo targetUserInfo;
20961        synchronized (this) {
20962            int currentUserId = mUserController.getCurrentUserIdLocked();
20963            currentUserInfo = mUserController.getUserInfo(currentUserId);
20964            targetUserInfo = mUserController.getUserInfo(targetUserId);
20965            if (targetUserInfo == null) {
20966                Slog.w(TAG, "No user info for user #" + targetUserId);
20967                return false;
20968            }
20969            if (!targetUserInfo.supportsSwitchTo()) {
20970                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
20971                return false;
20972            }
20973            if (targetUserInfo.isManagedProfile()) {
20974                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
20975                return false;
20976            }
20977            mUserController.setTargetUserIdLocked(targetUserId);
20978        }
20979        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
20980        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
20981        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
20982        return true;
20983    }
20984
20985    void scheduleStartProfilesLocked() {
20986        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
20987            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
20988                    DateUtils.SECOND_IN_MILLIS);
20989        }
20990    }
20991
20992    @Override
20993    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
20994        return mUserController.stopUser(userId, force, callback);
20995    }
20996
20997    @Override
20998    public UserInfo getCurrentUser() {
20999        return mUserController.getCurrentUser();
21000    }
21001
21002    @Override
21003    public boolean isUserRunning(int userId, int flags) {
21004        if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
21005                INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
21006            String msg = "Permission Denial: isUserRunning() from pid="
21007                    + Binder.getCallingPid()
21008                    + ", uid=" + Binder.getCallingUid()
21009                    + " requires " + INTERACT_ACROSS_USERS;
21010            Slog.w(TAG, msg);
21011            throw new SecurityException(msg);
21012        }
21013        synchronized (this) {
21014            return mUserController.isUserRunningLocked(userId, flags);
21015        }
21016    }
21017
21018    @Override
21019    public int[] getRunningUserIds() {
21020        if (checkCallingPermission(INTERACT_ACROSS_USERS)
21021                != PackageManager.PERMISSION_GRANTED) {
21022            String msg = "Permission Denial: isUserRunning() from pid="
21023                    + Binder.getCallingPid()
21024                    + ", uid=" + Binder.getCallingUid()
21025                    + " requires " + INTERACT_ACROSS_USERS;
21026            Slog.w(TAG, msg);
21027            throw new SecurityException(msg);
21028        }
21029        synchronized (this) {
21030            return mUserController.getStartedUserArrayLocked();
21031        }
21032    }
21033
21034    @Override
21035    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
21036        mUserController.registerUserSwitchObserver(observer);
21037    }
21038
21039    @Override
21040    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
21041        mUserController.unregisterUserSwitchObserver(observer);
21042    }
21043
21044    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
21045        if (info == null) return null;
21046        ApplicationInfo newInfo = new ApplicationInfo(info);
21047        newInfo.initForUser(userId);
21048        return newInfo;
21049    }
21050
21051    public boolean isUserStopped(int userId) {
21052        synchronized (this) {
21053            return mUserController.getStartedUserStateLocked(userId) == null;
21054        }
21055    }
21056
21057    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
21058        if (aInfo == null
21059                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
21060            return aInfo;
21061        }
21062
21063        ActivityInfo info = new ActivityInfo(aInfo);
21064        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
21065        return info;
21066    }
21067
21068    private boolean processSanityChecksLocked(ProcessRecord process) {
21069        if (process == null || process.thread == null) {
21070            return false;
21071        }
21072
21073        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21074        if (!isDebuggable) {
21075            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21076                return false;
21077            }
21078        }
21079
21080        return true;
21081    }
21082
21083    public boolean startBinderTracking() throws RemoteException {
21084        synchronized (this) {
21085            mBinderTransactionTrackingEnabled = true;
21086            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21087            // permission (same as profileControl).
21088            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21089                    != PackageManager.PERMISSION_GRANTED) {
21090                throw new SecurityException("Requires permission "
21091                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21092            }
21093
21094            for (int i = 0; i < mLruProcesses.size(); i++) {
21095                ProcessRecord process = mLruProcesses.get(i);
21096                if (!processSanityChecksLocked(process)) {
21097                    continue;
21098                }
21099                try {
21100                    process.thread.startBinderTracking();
21101                } catch (RemoteException e) {
21102                    Log.v(TAG, "Process disappared");
21103                }
21104            }
21105            return true;
21106        }
21107    }
21108
21109    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
21110        try {
21111            synchronized (this) {
21112                mBinderTransactionTrackingEnabled = false;
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                if (fd == null) {
21122                    throw new IllegalArgumentException("null fd");
21123                }
21124
21125                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
21126                pw.println("Binder transaction traces for all processes.\n");
21127                for (ProcessRecord process : mLruProcesses) {
21128                    if (!processSanityChecksLocked(process)) {
21129                        continue;
21130                    }
21131
21132                    pw.println("Traces for process: " + process.processName);
21133                    pw.flush();
21134                    try {
21135                        TransferPipe tp = new TransferPipe();
21136                        try {
21137                            process.thread.stopBinderTrackingAndDump(
21138                                    tp.getWriteFd().getFileDescriptor());
21139                            tp.go(fd.getFileDescriptor());
21140                        } finally {
21141                            tp.kill();
21142                        }
21143                    } catch (IOException e) {
21144                        pw.println("Failure while dumping IPC traces from " + process +
21145                                ".  Exception: " + e);
21146                        pw.flush();
21147                    } catch (RemoteException e) {
21148                        pw.println("Got a RemoteException while dumping IPC traces from " +
21149                                process + ".  Exception: " + e);
21150                        pw.flush();
21151                    }
21152                }
21153                fd = null;
21154                return true;
21155            }
21156        } finally {
21157            if (fd != null) {
21158                try {
21159                    fd.close();
21160                } catch (IOException e) {
21161                }
21162            }
21163        }
21164    }
21165
21166    private final class LocalService extends ActivityManagerInternal {
21167        @Override
21168        public void onWakefulnessChanged(int wakefulness) {
21169            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21170        }
21171
21172        @Override
21173        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21174                String processName, String abiOverride, int uid, Runnable crashHandler) {
21175            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21176                    processName, abiOverride, uid, crashHandler);
21177        }
21178
21179        @Override
21180        public SleepToken acquireSleepToken(String tag) {
21181            Preconditions.checkNotNull(tag);
21182
21183            synchronized (ActivityManagerService.this) {
21184                SleepTokenImpl token = new SleepTokenImpl(tag);
21185                mSleepTokens.add(token);
21186                updateSleepIfNeededLocked();
21187                applyVrModeIfNeededLocked(mFocusedActivity, false);
21188                return token;
21189            }
21190        }
21191
21192        @Override
21193        public ComponentName getHomeActivityForUser(int userId) {
21194            synchronized (ActivityManagerService.this) {
21195                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21196                return homeActivity == null ? null : homeActivity.realActivity;
21197            }
21198        }
21199
21200        @Override
21201        public void onUserRemoved(int userId) {
21202            synchronized (ActivityManagerService.this) {
21203                ActivityManagerService.this.onUserStoppedLocked(userId);
21204            }
21205        }
21206
21207        @Override
21208        public void onLocalVoiceInteractionStarted(IBinder activity,
21209                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
21210            synchronized (ActivityManagerService.this) {
21211                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21212                        voiceSession, voiceInteractor);
21213            }
21214        }
21215
21216        @Override
21217        public void notifyStartingWindowDrawn() {
21218            synchronized (ActivityManagerService.this) {
21219                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
21220            }
21221        }
21222
21223        @Override
21224        public void notifyAppTransitionStarting(int reason) {
21225            synchronized (ActivityManagerService.this) {
21226                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
21227            }
21228        }
21229
21230        @Override
21231        public void notifyAppTransitionFinished() {
21232            synchronized (ActivityManagerService.this) {
21233                mStackSupervisor.notifyAppTransitionDone();
21234            }
21235        }
21236
21237        @Override
21238        public void notifyAppTransitionCancelled() {
21239            synchronized (ActivityManagerService.this) {
21240                mStackSupervisor.notifyAppTransitionDone();
21241            }
21242        }
21243
21244        @Override
21245        public List<IBinder> getTopVisibleActivities() {
21246            synchronized (ActivityManagerService.this) {
21247                return mStackSupervisor.getTopVisibleActivities();
21248            }
21249        }
21250
21251        @Override
21252        public void notifyDockedStackMinimizedChanged(boolean minimized) {
21253            synchronized (ActivityManagerService.this) {
21254                mStackSupervisor.setDockedStackMinimized(minimized);
21255            }
21256        }
21257
21258        @Override
21259        public void killForegroundAppsForUser(int userHandle) {
21260            synchronized (ActivityManagerService.this) {
21261                final ArrayList<ProcessRecord> procs = new ArrayList<>();
21262                final int NP = mProcessNames.getMap().size();
21263                for (int ip = 0; ip < NP; ip++) {
21264                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
21265                    final int NA = apps.size();
21266                    for (int ia = 0; ia < NA; ia++) {
21267                        final ProcessRecord app = apps.valueAt(ia);
21268                        if (app.persistent) {
21269                            // We don't kill persistent processes.
21270                            continue;
21271                        }
21272                        if (app.removed) {
21273                            procs.add(app);
21274                        } else if (app.userId == userHandle && app.foregroundActivities) {
21275                            app.removed = true;
21276                            procs.add(app);
21277                        }
21278                    }
21279                }
21280
21281                final int N = procs.size();
21282                for (int i = 0; i < N; i++) {
21283                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
21284                }
21285            }
21286        }
21287    }
21288
21289    private final class SleepTokenImpl extends SleepToken {
21290        private final String mTag;
21291        private final long mAcquireTime;
21292
21293        public SleepTokenImpl(String tag) {
21294            mTag = tag;
21295            mAcquireTime = SystemClock.uptimeMillis();
21296        }
21297
21298        @Override
21299        public void release() {
21300            synchronized (ActivityManagerService.this) {
21301                if (mSleepTokens.remove(this)) {
21302                    updateSleepIfNeededLocked();
21303                }
21304            }
21305        }
21306
21307        @Override
21308        public String toString() {
21309            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
21310        }
21311    }
21312
21313    /**
21314     * An implementation of IAppTask, that allows an app to manage its own tasks via
21315     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
21316     * only the process that calls getAppTasks() can call the AppTask methods.
21317     */
21318    class AppTaskImpl extends IAppTask.Stub {
21319        private int mTaskId;
21320        private int mCallingUid;
21321
21322        public AppTaskImpl(int taskId, int callingUid) {
21323            mTaskId = taskId;
21324            mCallingUid = callingUid;
21325        }
21326
21327        private void checkCaller() {
21328            if (mCallingUid != Binder.getCallingUid()) {
21329                throw new SecurityException("Caller " + mCallingUid
21330                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
21331            }
21332        }
21333
21334        @Override
21335        public void finishAndRemoveTask() {
21336            checkCaller();
21337
21338            synchronized (ActivityManagerService.this) {
21339                long origId = Binder.clearCallingIdentity();
21340                try {
21341                    // We remove the task from recents to preserve backwards
21342                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
21343                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21344                    }
21345                } finally {
21346                    Binder.restoreCallingIdentity(origId);
21347                }
21348            }
21349        }
21350
21351        @Override
21352        public ActivityManager.RecentTaskInfo getTaskInfo() {
21353            checkCaller();
21354
21355            synchronized (ActivityManagerService.this) {
21356                long origId = Binder.clearCallingIdentity();
21357                try {
21358                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21359                    if (tr == null) {
21360                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21361                    }
21362                    return createRecentTaskInfoFromTaskRecord(tr);
21363                } finally {
21364                    Binder.restoreCallingIdentity(origId);
21365                }
21366            }
21367        }
21368
21369        @Override
21370        public void moveToFront() {
21371            checkCaller();
21372            // Will bring task to front if it already has a root activity.
21373            final long origId = Binder.clearCallingIdentity();
21374            try {
21375                synchronized (this) {
21376                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
21377                }
21378            } finally {
21379                Binder.restoreCallingIdentity(origId);
21380            }
21381        }
21382
21383        @Override
21384        public int startActivity(IBinder whoThread, String callingPackage,
21385                Intent intent, String resolvedType, Bundle bOptions) {
21386            checkCaller();
21387
21388            int callingUser = UserHandle.getCallingUserId();
21389            TaskRecord tr;
21390            IApplicationThread appThread;
21391            synchronized (ActivityManagerService.this) {
21392                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21393                if (tr == null) {
21394                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21395                }
21396                appThread = ApplicationThreadNative.asInterface(whoThread);
21397                if (appThread == null) {
21398                    throw new IllegalArgumentException("Bad app thread " + appThread);
21399                }
21400            }
21401            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
21402                    resolvedType, null, null, null, null, 0, 0, null, null,
21403                    null, bOptions, false, callingUser, null, tr);
21404        }
21405
21406        @Override
21407        public void setExcludeFromRecents(boolean exclude) {
21408            checkCaller();
21409
21410            synchronized (ActivityManagerService.this) {
21411                long origId = Binder.clearCallingIdentity();
21412                try {
21413                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21414                    if (tr == null) {
21415                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21416                    }
21417                    Intent intent = tr.getBaseIntent();
21418                    if (exclude) {
21419                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21420                    } else {
21421                        intent.setFlags(intent.getFlags()
21422                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21423                    }
21424                } finally {
21425                    Binder.restoreCallingIdentity(origId);
21426                }
21427            }
21428        }
21429    }
21430
21431    /**
21432     * Kill processes for the user with id userId and that depend on the package named packageName
21433     */
21434    @Override
21435    public void killPackageDependents(String packageName, int userId) {
21436        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
21437        if (packageName == null) {
21438            throw new NullPointerException(
21439                    "Cannot kill the dependents of a package without its name.");
21440        }
21441
21442        long callingId = Binder.clearCallingIdentity();
21443        IPackageManager pm = AppGlobals.getPackageManager();
21444        int pkgUid = -1;
21445        try {
21446            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
21447        } catch (RemoteException e) {
21448        }
21449        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
21450            throw new IllegalArgumentException(
21451                    "Cannot kill dependents of non-existing package " + packageName);
21452        }
21453        try {
21454            synchronized(this) {
21455                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
21456                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
21457                        "dep: " + packageName);
21458            }
21459        } finally {
21460            Binder.restoreCallingIdentity(callingId);
21461        }
21462    }
21463}
21464