ActivityManagerService.java revision 6eee8e37fd06bd47dd19b8503bc30cc8ccaf72a7
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.server.AppOpsService;
45import com.android.server.AttributeCache;
46import com.android.server.DeviceIdleController;
47import com.android.server.IntentResolver;
48import com.android.server.LocalServices;
49import com.android.server.LockGuard;
50import com.android.server.ServiceThread;
51import com.android.server.SystemService;
52import com.android.server.SystemServiceManager;
53import com.android.server.Watchdog;
54import com.android.server.am.ActivityStack.ActivityState;
55import com.android.server.firewall.IntentFirewall;
56import com.android.server.pm.Installer;
57import com.android.server.statusbar.StatusBarManagerInternal;
58import com.android.server.vr.VrManagerInternal;
59import com.android.server.wm.WindowManagerService;
60
61import org.xmlpull.v1.XmlPullParser;
62import org.xmlpull.v1.XmlPullParserException;
63import org.xmlpull.v1.XmlSerializer;
64
65import android.Manifest;
66import android.Manifest.permission;
67import android.annotation.NonNull;
68import android.annotation.UserIdInt;
69import android.app.Activity;
70import android.app.ActivityManager;
71import android.app.ActivityManager.RunningTaskInfo;
72import android.app.ActivityManager.StackId;
73import android.app.ActivityManager.StackInfo;
74import android.app.ActivityManager.TaskThumbnailInfo;
75import android.app.ActivityManagerInternal;
76import android.app.ActivityManagerInternal.SleepToken;
77import android.app.ActivityManagerNative;
78import android.app.ActivityOptions;
79import android.app.ActivityThread;
80import android.app.AlertDialog;
81import android.app.AppGlobals;
82import android.app.AppOpsManager;
83import android.app.ApplicationErrorReport;
84import android.app.ApplicationThreadNative;
85import android.app.BroadcastOptions;
86import android.app.Dialog;
87import android.app.IActivityContainer;
88import android.app.IActivityContainerCallback;
89import android.app.IActivityController;
90import android.app.IAppTask;
91import android.app.IApplicationThread;
92import android.app.IInstrumentationWatcher;
93import android.app.INotificationManager;
94import android.app.IProcessObserver;
95import android.app.IServiceConnection;
96import android.app.IStopUserCallback;
97import android.app.ITaskStackListener;
98import android.app.IUiAutomationConnection;
99import android.app.IUidObserver;
100import android.app.IUserSwitchObserver;
101import android.app.Instrumentation;
102import android.app.Notification;
103import android.app.NotificationManager;
104import android.app.PendingIntent;
105import android.app.ProfilerInfo;
106import android.app.admin.DevicePolicyManager;
107import android.app.assist.AssistContent;
108import android.app.assist.AssistStructure;
109import android.app.backup.IBackupManager;
110import android.app.usage.UsageEvents;
111import android.app.usage.UsageStatsManagerInternal;
112import android.appwidget.AppWidgetManager;
113import android.content.ActivityNotFoundException;
114import android.content.BroadcastReceiver;
115import android.content.ClipData;
116import android.content.ComponentCallbacks2;
117import android.content.ComponentName;
118import android.content.ContentProvider;
119import android.content.ContentResolver;
120import android.content.Context;
121import android.content.DialogInterface;
122import android.content.IContentProvider;
123import android.content.IIntentReceiver;
124import android.content.IIntentSender;
125import android.content.Intent;
126import android.content.IntentFilter;
127import android.content.IntentSender;
128import android.content.pm.ActivityInfo;
129import android.content.pm.ApplicationInfo;
130import android.content.pm.ConfigurationInfo;
131import android.content.pm.IPackageDataObserver;
132import android.content.pm.IPackageManager;
133import android.content.pm.InstrumentationInfo;
134import android.content.pm.PackageInfo;
135import android.content.pm.PackageManager;
136import android.content.pm.PackageManager.NameNotFoundException;
137import android.content.pm.PackageManagerInternal;
138import android.content.pm.ParceledListSlice;
139import android.content.pm.PathPermission;
140import android.content.pm.PermissionInfo;
141import android.content.pm.ProviderInfo;
142import android.content.pm.ResolveInfo;
143import android.content.pm.ServiceInfo;
144import android.content.pm.UserInfo;
145import android.content.res.CompatibilityInfo;
146import android.content.res.Configuration;
147import android.content.res.Resources;
148import android.database.ContentObserver;
149import android.graphics.Bitmap;
150import android.graphics.Point;
151import android.graphics.Rect;
152import android.location.LocationManager;
153import android.net.Proxy;
154import android.net.ProxyInfo;
155import android.net.Uri;
156import android.os.BatteryStats;
157import android.os.Binder;
158import android.os.Build;
159import android.os.Bundle;
160import android.os.Debug;
161import android.os.DropBoxManager;
162import android.os.Environment;
163import android.os.FactoryTest;
164import android.os.FileObserver;
165import android.os.FileUtils;
166import android.os.Handler;
167import android.os.IBinder;
168import android.os.IPermissionController;
169import android.os.IProcessInfoService;
170import android.os.IProgressListener;
171import android.os.LocaleList;
172import android.os.Looper;
173import android.os.Message;
174import android.os.Parcel;
175import android.os.ParcelFileDescriptor;
176import android.os.PersistableBundle;
177import android.os.PowerManager;
178import android.os.PowerManagerInternal;
179import android.os.Process;
180import android.os.RemoteCallbackList;
181import android.os.RemoteException;
182import android.os.ResultReceiver;
183import android.os.ServiceManager;
184import android.os.StrictMode;
185import android.os.SystemClock;
186import android.os.SystemProperties;
187import android.os.Trace;
188import android.os.TransactionTooLargeException;
189import android.os.UpdateLock;
190import android.os.UserHandle;
191import android.os.UserManager;
192import android.os.WorkSource;
193import android.provider.Downloads;
194import android.os.storage.IMountService;
195import android.os.storage.MountServiceInternal;
196import android.os.storage.StorageManager;
197import android.provider.Settings;
198import android.service.voice.IVoiceInteractionSession;
199import android.service.voice.VoiceInteractionManagerInternal;
200import android.service.voice.VoiceInteractionSession;
201import android.telecom.TelecomManager;
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.DisplayMetrics;
210import android.util.EventLog;
211import android.util.Log;
212import android.util.Pair;
213import android.util.PrintWriterPrinter;
214import android.util.Slog;
215import android.util.SparseArray;
216import android.util.TimeUtils;
217import android.util.Xml;
218import android.view.Display;
219import android.view.Gravity;
220import android.view.LayoutInflater;
221import android.view.View;
222import android.view.WindowManager;
223
224import java.io.File;
225import java.io.FileDescriptor;
226import java.io.FileInputStream;
227import java.io.FileNotFoundException;
228import java.io.FileOutputStream;
229import java.io.IOException;
230import java.io.InputStreamReader;
231import java.io.PrintWriter;
232import java.io.StringWriter;
233import java.lang.ref.WeakReference;
234import java.nio.charset.StandardCharsets;
235import java.util.ArrayList;
236import java.util.Arrays;
237import java.util.Collections;
238import java.util.Comparator;
239import java.util.HashMap;
240import java.util.HashSet;
241import java.util.Iterator;
242import java.util.List;
243import java.util.Locale;
244import java.util.Map;
245import java.util.Objects;
246import java.util.Set;
247import java.util.concurrent.atomic.AtomicBoolean;
248import java.util.concurrent.atomic.AtomicLong;
249
250import dalvik.system.VMRuntime;
251
252import libcore.io.IoUtils;
253import libcore.util.EmptyArray;
254
255import static android.Manifest.permission.INTERACT_ACROSS_USERS;
256import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
257import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
258import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
259import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
260import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
261import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
262import static android.app.ActivityManager.StackId.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.PINNED_STACK_ID;
267import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
268import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
269import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
270import static android.content.pm.PackageManager.GET_PROVIDERS;
271import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
272import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
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.os.Process.PROC_CHAR;
279import static android.os.Process.PROC_OUT_LONG;
280import static android.os.Process.PROC_PARENS;
281import static android.os.Process.PROC_SPACE_TERM;
282import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
283import static android.provider.Settings.Global.DEBUG_APP;
284import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
285import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
286import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
287import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
288import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
289import static android.provider.Settings.System.FONT_SCALE;
290import static com.android.internal.util.XmlUtils.readBooleanAttribute;
291import static com.android.internal.util.XmlUtils.readIntAttribute;
292import static com.android.internal.util.XmlUtils.readLongAttribute;
293import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
294import static com.android.internal.util.XmlUtils.writeIntAttribute;
295import static com.android.internal.util.XmlUtils.writeLongAttribute;
296import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
297import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
298import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
299import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
300import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
301import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
302import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
303import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
304import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
305import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
306import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
307import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
308import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
309import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
310import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
311import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
312import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
313import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
314import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
315import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
316import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
317import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
318import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
319import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
320import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
321import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
322import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
323import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
324import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
325import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
326import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
327import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
328import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
329import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
330import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
331import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
332import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
333import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
334import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
335import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
336import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
337import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
338import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
339import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
340import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
341import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
342import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
343import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
344import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
345import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
346import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
347import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
348import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
349import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
350import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
351import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
352import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
353import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
354import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
355import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
356import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
357import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
358import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
359import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
360import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
361import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
362import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
363import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
364import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
365import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
366import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
367import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
368import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
369import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
370import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
371import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
372import static org.xmlpull.v1.XmlPullParser.START_TAG;
373
374public final class ActivityManagerService extends ActivityManagerNative
375        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
376
377    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
378    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
379    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
380    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
381    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
382    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
383    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
384    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
385    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
386    private static final String TAG_LRU = TAG + POSTFIX_LRU;
387    private static final String TAG_MU = TAG + POSTFIX_MU;
388    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
389    private static final String TAG_POWER = TAG + POSTFIX_POWER;
390    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
391    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
392    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
393    private static final String TAG_PSS = TAG + POSTFIX_PSS;
394    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
395    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
396    private static final String TAG_STACK = TAG + POSTFIX_STACK;
397    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
398    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
399    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
400    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
401    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
402
403    // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
404    // here so that while the job scheduler can depend on AMS, the other way around
405    // need not be the case.
406    public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
407
408    /** Control over CPU and battery monitoring */
409    // write battery stats every 30 minutes.
410    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
411    static final boolean MONITOR_CPU_USAGE = true;
412    // don't sample cpu less than every 5 seconds.
413    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
414    // wait possibly forever for next cpu sample.
415    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
416    static final boolean MONITOR_THREAD_CPU_USAGE = false;
417
418    // The flags that are set for all calls we make to the package manager.
419    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
420
421    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
422
423    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
424
425    // Amount of time after a call to stopAppSwitches() during which we will
426    // prevent further untrusted switches from happening.
427    static final long APP_SWITCH_DELAY_TIME = 5*1000;
428
429    // How long we wait for a launched process to attach to the activity manager
430    // before we decide it's never going to come up for real.
431    static final int PROC_START_TIMEOUT = 10*1000;
432    // How long we wait for an attached process to publish its content providers
433    // before we decide it must be hung.
434    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
435
436    // How long we will retain processes hosting content providers in the "last activity"
437    // state before allowing them to drop down to the regular cached LRU list.  This is
438    // to avoid thrashing of provider processes under low memory situations.
439    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
440
441    // How long we wait for a launched process to attach to the activity manager
442    // before we decide it's never going to come up for real, when the process was
443    // started with a wrapper for instrumentation (such as Valgrind) because it
444    // could take much longer than usual.
445    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
446
447    // How long to wait after going idle before forcing apps to GC.
448    static final int GC_TIMEOUT = 5*1000;
449
450    // The minimum amount of time between successive GC requests for a process.
451    static final int GC_MIN_INTERVAL = 60*1000;
452
453    // The minimum amount of time between successive PSS requests for a process.
454    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
455
456    // The minimum amount of time between successive PSS requests for a process
457    // when the request is due to the memory state being lowered.
458    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
459
460    // The rate at which we check for apps using excessive power -- 15 mins.
461    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
462
463    // The minimum sample duration we will allow before deciding we have
464    // enough data on wake locks to start killing things.
465    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
466
467    // The minimum sample duration we will allow before deciding we have
468    // enough data on CPU usage to start killing things.
469    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
470
471    // How long we allow a receiver to run before giving up on it.
472    static final int BROADCAST_FG_TIMEOUT = 10*1000;
473    static final int BROADCAST_BG_TIMEOUT = 60*1000;
474
475    // How long we wait until we timeout on key dispatching.
476    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
477
478    // How long we wait until we timeout on key dispatching during instrumentation.
479    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
480
481    // This is the amount of time an app needs to be running a foreground service before
482    // we will consider it to be doing interaction for usage stats.
483    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
484
485    // Maximum amount of time we will allow to elapse before re-reporting usage stats
486    // interaction with foreground processes.
487    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
488
489    // This is the amount of time we allow an app to settle after it goes into the background,
490    // before we start restricting what it can do.
491    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
492
493    // How long to wait in getAssistContextExtras for the activity and foreground services
494    // to respond with the result.
495    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
496
497    // How long top wait when going through the modern assist (which doesn't need to block
498    // on getting this result before starting to launch its UI).
499    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
500
501    // Maximum number of persisted Uri grants a package is allowed
502    static final int MAX_PERSISTED_URI_GRANTS = 128;
503
504    static final int MY_PID = Process.myPid();
505
506    static final String[] EMPTY_STRING_ARRAY = new String[0];
507
508    // How many bytes to write into the dropbox log before truncating
509    static final int DROPBOX_MAX_SIZE = 192 * 1024;
510    // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
511    // as one line, but close enough for now.
512    static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
513
514    // Access modes for handleIncomingUser.
515    static final int ALLOW_NON_FULL = 0;
516    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
517    static final int ALLOW_FULL_ONLY = 2;
518
519    // Delay in notifying task stack change listeners (in millis)
520    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
521
522    // Necessary ApplicationInfo flags to mark an app as persistent
523    private static final int PERSISTENT_MASK =
524            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
525
526    // Intent sent when remote bugreport collection has been completed
527    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
528            "android.intent.action.REMOTE_BUGREPORT_FINISHED";
529
530    // Delay to disable app launch boost
531    static final int APP_BOOST_MESSAGE_DELAY = 3000;
532    // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
533    static final int APP_BOOST_TIMEOUT = 2500;
534
535    // Used to indicate that a task is removed it should also be removed from recents.
536    private static final boolean REMOVE_FROM_RECENTS = true;
537    // Used to indicate that an app transition should be animated.
538    static final boolean ANIMATE = true;
539
540    // Determines whether to take full screen screenshots
541    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
542    public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
543
544    private static native int nativeMigrateToBoost();
545    private static native int nativeMigrateFromBoost();
546    private boolean mIsBoosted = false;
547    private long mBoostStartTime = 0;
548
549    /** All system services */
550    SystemServiceManager mSystemServiceManager;
551
552    private Installer mInstaller;
553
554    /** Run all ActivityStacks through this */
555    final ActivityStackSupervisor mStackSupervisor;
556
557    final ActivityStarter mActivityStarter;
558
559    /** Task stack change listeners. */
560    private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
561            new RemoteCallbackList<ITaskStackListener>();
562
563    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
564
565    public IntentFirewall mIntentFirewall;
566
567    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
568    // default actuion automatically.  Important for devices without direct input
569    // devices.
570    private boolean mShowDialogs = true;
571    private boolean mInVrMode = false;
572
573    // Whether we should use SCHED_FIFO for UI and RenderThreads.
574    private boolean mUseFifoUiScheduling = false;
575
576    BroadcastQueue mFgBroadcastQueue;
577    BroadcastQueue mBgBroadcastQueue;
578    // Convenient for easy iteration over the queues. Foreground is first
579    // so that dispatch of foreground broadcasts gets precedence.
580    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
581
582    BroadcastStats mLastBroadcastStats;
583    BroadcastStats mCurBroadcastStats;
584
585    BroadcastQueue broadcastQueueForIntent(Intent intent) {
586        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
587        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
588                "Broadcast intent " + intent + " on "
589                + (isFg ? "foreground" : "background") + " queue");
590        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
591    }
592
593    /**
594     * Activity we have told the window manager to have key focus.
595     */
596    ActivityRecord mFocusedActivity = null;
597
598    /**
599     * User id of the last activity mFocusedActivity was set to.
600     */
601    private int mLastFocusedUserId;
602
603    /**
604     * If non-null, we are tracking the time the user spends in the currently focused app.
605     */
606    private AppTimeTracker mCurAppTimeTracker;
607
608    /**
609     * List of intents that were used to start the most recent tasks.
610     */
611    final RecentTasks mRecentTasks;
612
613    /**
614     * For addAppTask: cached of the last activity component that was added.
615     */
616    ComponentName mLastAddedTaskComponent;
617
618    /**
619     * For addAppTask: cached of the last activity uid that was added.
620     */
621    int mLastAddedTaskUid;
622
623    /**
624     * For addAppTask: cached of the last ActivityInfo that was added.
625     */
626    ActivityInfo mLastAddedTaskActivity;
627
628    /**
629     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
630     */
631    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
632
633    /**
634     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
635     */
636    String mDeviceOwnerName;
637
638    final UserController mUserController;
639
640    final AppErrors mAppErrors;
641
642    boolean mDoingSetFocusedActivity;
643
644    public boolean canShowErrorDialogs() {
645        return mShowDialogs && !mSleeping && !mShuttingDown
646                && mLockScreenShown != LOCK_SCREEN_SHOWN;
647    }
648
649    private static final class PriorityState {
650        // Acts as counter for number of synchronized region that needs to acquire 'this' as a lock
651        // the current thread is currently in. When it drops down to zero, we will no longer boost
652        // the thread's priority.
653        private int regionCounter = 0;
654
655        // The thread's previous priority before boosting.
656        private int prevPriority = Integer.MIN_VALUE;
657    }
658
659    static ThreadLocal<PriorityState> sThreadPriorityState = new ThreadLocal<PriorityState>() {
660        @Override protected PriorityState initialValue() {
661            return new PriorityState();
662        }
663    };
664
665    static void boostPriorityForLockedSection() {
666        int tid = Process.myTid();
667        int prevPriority = Process.getThreadPriority(tid);
668        PriorityState state = sThreadPriorityState.get();
669        if (state.regionCounter == 0 && prevPriority > -2) {
670            state.prevPriority = prevPriority;
671            Process.setThreadPriority(tid, -2);
672        }
673        state.regionCounter++;
674    }
675
676    static void resetPriorityAfterLockedSection() {
677        PriorityState state = sThreadPriorityState.get();
678        state.regionCounter--;
679        if (state.regionCounter == 0 && state.prevPriority > -2) {
680            Process.setThreadPriority(Process.myTid(), state.prevPriority);
681        }
682    }
683
684    public class PendingAssistExtras extends Binder implements Runnable {
685        public final ActivityRecord activity;
686        public final Bundle extras;
687        public final Intent intent;
688        public final String hint;
689        public final IResultReceiver receiver;
690        public final int userHandle;
691        public boolean haveResult = false;
692        public Bundle result = null;
693        public AssistStructure structure = null;
694        public AssistContent content = null;
695        public Bundle receiverExtras;
696
697        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
698                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
699            activity = _activity;
700            extras = _extras;
701            intent = _intent;
702            hint = _hint;
703            receiver = _receiver;
704            receiverExtras = _receiverExtras;
705            userHandle = _userHandle;
706        }
707        @Override
708        public void run() {
709            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
710            synchronized (this) {
711                haveResult = true;
712                notifyAll();
713            }
714            pendingAssistExtrasTimedOut(this);
715        }
716    }
717
718    final ArrayList<PendingAssistExtras> mPendingAssistExtras
719            = new ArrayList<PendingAssistExtras>();
720
721    /**
722     * Process management.
723     */
724    final ProcessList mProcessList = new ProcessList();
725
726    /**
727     * All of the applications we currently have running organized by name.
728     * The keys are strings of the application package name (as
729     * returned by the package manager), and the keys are ApplicationRecord
730     * objects.
731     */
732    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
733
734    /**
735     * Tracking long-term execution of processes to look for abuse and other
736     * bad app behavior.
737     */
738    final ProcessStatsService mProcessStats;
739
740    /**
741     * The currently running isolated processes.
742     */
743    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
744
745    /**
746     * Counter for assigning isolated process uids, to avoid frequently reusing the
747     * same ones.
748     */
749    int mNextIsolatedProcessUid = 0;
750
751    /**
752     * The currently running heavy-weight process, if any.
753     */
754    ProcessRecord mHeavyWeightProcess = null;
755
756    /**
757     * All of the processes we currently have running organized by pid.
758     * The keys are the pid running the application.
759     *
760     * <p>NOTE: This object is protected by its own lock, NOT the global
761     * activity manager lock!
762     */
763    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
764
765    /**
766     * All of the processes that have been forced to be foreground.  The key
767     * is the pid of the caller who requested it (we hold a death
768     * link on it).
769     */
770    abstract class ForegroundToken implements IBinder.DeathRecipient {
771        int pid;
772        IBinder token;
773    }
774    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
775
776    /**
777     * List of records for processes that someone had tried to start before the
778     * system was ready.  We don't start them at that point, but ensure they
779     * are started by the time booting is complete.
780     */
781    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
782
783    /**
784     * List of persistent applications that are in the process
785     * of being started.
786     */
787    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
788
789    /**
790     * Processes that are being forcibly torn down.
791     */
792    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
793
794    /**
795     * List of running applications, sorted by recent usage.
796     * The first entry in the list is the least recently used.
797     */
798    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
799
800    /**
801     * Where in mLruProcesses that the processes hosting activities start.
802     */
803    int mLruProcessActivityStart = 0;
804
805    /**
806     * Where in mLruProcesses that the processes hosting services start.
807     * This is after (lower index) than mLruProcessesActivityStart.
808     */
809    int mLruProcessServiceStart = 0;
810
811    /**
812     * List of processes that should gc as soon as things are idle.
813     */
814    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
815
816    /**
817     * Processes we want to collect PSS data from.
818     */
819    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
820
821    private boolean mBinderTransactionTrackingEnabled = false;
822
823    /**
824     * Last time we requested PSS data of all processes.
825     */
826    long mLastFullPssTime = SystemClock.uptimeMillis();
827
828    /**
829     * If set, the next time we collect PSS data we should do a full collection
830     * with data from native processes and the kernel.
831     */
832    boolean mFullPssPending = false;
833
834    /**
835     * This is the process holding what we currently consider to be
836     * the "home" activity.
837     */
838    ProcessRecord mHomeProcess;
839
840    /**
841     * This is the process holding the activity the user last visited that
842     * is in a different process from the one they are currently in.
843     */
844    ProcessRecord mPreviousProcess;
845
846    /**
847     * The time at which the previous process was last visible.
848     */
849    long mPreviousProcessVisibleTime;
850
851    /**
852     * Track all uids that have actively running processes.
853     */
854    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
855
856    /**
857     * This is for verifying the UID report flow.
858     */
859    static final boolean VALIDATE_UID_STATES = true;
860    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
861
862    /**
863     * Packages that the user has asked to have run in screen size
864     * compatibility mode instead of filling the screen.
865     */
866    final CompatModePackages mCompatModePackages;
867
868    /**
869     * Set of IntentSenderRecord objects that are currently active.
870     */
871    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
872            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
873
874    /**
875     * Fingerprints (hashCode()) of stack traces that we've
876     * already logged DropBox entries for.  Guarded by itself.  If
877     * something (rogue user app) forces this over
878     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
879     */
880    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
881    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
882
883    /**
884     * Strict Mode background batched logging state.
885     *
886     * The string buffer is guarded by itself, and its lock is also
887     * used to determine if another batched write is already
888     * in-flight.
889     */
890    private final StringBuilder mStrictModeBuffer = new StringBuilder();
891
892    /**
893     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
894     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
895     */
896    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
897
898    /**
899     * Resolver for broadcast intents to registered receivers.
900     * Holds BroadcastFilter (subclass of IntentFilter).
901     */
902    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
903            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
904        @Override
905        protected boolean allowFilterResult(
906                BroadcastFilter filter, List<BroadcastFilter> dest) {
907            IBinder target = filter.receiverList.receiver.asBinder();
908            for (int i = dest.size() - 1; i >= 0; i--) {
909                if (dest.get(i).receiverList.receiver.asBinder() == target) {
910                    return false;
911                }
912            }
913            return true;
914        }
915
916        @Override
917        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
918            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
919                    || userId == filter.owningUserId) {
920                return super.newResult(filter, match, userId);
921            }
922            return null;
923        }
924
925        @Override
926        protected BroadcastFilter[] newArray(int size) {
927            return new BroadcastFilter[size];
928        }
929
930        @Override
931        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
932            return packageName.equals(filter.packageName);
933        }
934    };
935
936    /**
937     * State of all active sticky broadcasts per user.  Keys are the action of the
938     * sticky Intent, values are an ArrayList of all broadcasted intents with
939     * that action (which should usually be one).  The SparseArray is keyed
940     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
941     * for stickies that are sent to all users.
942     */
943    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
944            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
945
946    final ActiveServices mServices;
947
948    final static class Association {
949        final int mSourceUid;
950        final String mSourceProcess;
951        final int mTargetUid;
952        final ComponentName mTargetComponent;
953        final String mTargetProcess;
954
955        int mCount;
956        long mTime;
957
958        int mNesting;
959        long mStartTime;
960
961        // states of the source process when the bind occurred.
962        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
963        long mLastStateUptime;
964        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
965                - ActivityManager.MIN_PROCESS_STATE+1];
966
967        Association(int sourceUid, String sourceProcess, int targetUid,
968                ComponentName targetComponent, String targetProcess) {
969            mSourceUid = sourceUid;
970            mSourceProcess = sourceProcess;
971            mTargetUid = targetUid;
972            mTargetComponent = targetComponent;
973            mTargetProcess = targetProcess;
974        }
975    }
976
977    /**
978     * When service association tracking is enabled, this is all of the associations we
979     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
980     * -> association data.
981     */
982    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
983            mAssociations = new SparseArray<>();
984    boolean mTrackingAssociations;
985
986    /**
987     * Backup/restore process management
988     */
989    String mBackupAppName = null;
990    BackupRecord mBackupTarget = null;
991
992    final ProviderMap mProviderMap;
993
994    /**
995     * List of content providers who have clients waiting for them.  The
996     * application is currently being launched and the provider will be
997     * removed from this list once it is published.
998     */
999    final ArrayList<ContentProviderRecord> mLaunchingProviders
1000            = new ArrayList<ContentProviderRecord>();
1001
1002    /**
1003     * File storing persisted {@link #mGrantedUriPermissions}.
1004     */
1005    private final AtomicFile mGrantFile;
1006
1007    /** XML constants used in {@link #mGrantFile} */
1008    private static final String TAG_URI_GRANTS = "uri-grants";
1009    private static final String TAG_URI_GRANT = "uri-grant";
1010    private static final String ATTR_USER_HANDLE = "userHandle";
1011    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
1012    private static final String ATTR_TARGET_USER_ID = "targetUserId";
1013    private static final String ATTR_SOURCE_PKG = "sourcePkg";
1014    private static final String ATTR_TARGET_PKG = "targetPkg";
1015    private static final String ATTR_URI = "uri";
1016    private static final String ATTR_MODE_FLAGS = "modeFlags";
1017    private static final String ATTR_CREATED_TIME = "createdTime";
1018    private static final String ATTR_PREFIX = "prefix";
1019
1020    /**
1021     * Global set of specific {@link Uri} permissions that have been granted.
1022     * This optimized lookup structure maps from {@link UriPermission#targetUid}
1023     * to {@link UriPermission#uri} to {@link UriPermission}.
1024     */
1025    @GuardedBy("this")
1026    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1027            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1028
1029    public static class GrantUri {
1030        public final int sourceUserId;
1031        public final Uri uri;
1032        public boolean prefix;
1033
1034        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1035            this.sourceUserId = sourceUserId;
1036            this.uri = uri;
1037            this.prefix = prefix;
1038        }
1039
1040        @Override
1041        public int hashCode() {
1042            int hashCode = 1;
1043            hashCode = 31 * hashCode + sourceUserId;
1044            hashCode = 31 * hashCode + uri.hashCode();
1045            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1046            return hashCode;
1047        }
1048
1049        @Override
1050        public boolean equals(Object o) {
1051            if (o instanceof GrantUri) {
1052                GrantUri other = (GrantUri) o;
1053                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1054                        && prefix == other.prefix;
1055            }
1056            return false;
1057        }
1058
1059        @Override
1060        public String toString() {
1061            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1062            if (prefix) result += " [prefix]";
1063            return result;
1064        }
1065
1066        public String toSafeString() {
1067            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1068            if (prefix) result += " [prefix]";
1069            return result;
1070        }
1071
1072        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1073            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1074                    ContentProvider.getUriWithoutUserId(uri), false);
1075        }
1076    }
1077
1078    CoreSettingsObserver mCoreSettingsObserver;
1079
1080    FontScaleSettingObserver mFontScaleSettingObserver;
1081
1082    private final class FontScaleSettingObserver extends ContentObserver {
1083        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1084
1085        public FontScaleSettingObserver() {
1086            super(mHandler);
1087            ContentResolver resolver = mContext.getContentResolver();
1088            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1089        }
1090
1091        @Override
1092        public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1093            if (mFontScaleUri.equals(uri)) {
1094                updateFontScaleIfNeeded(userId);
1095            }
1096        }
1097    }
1098
1099    /**
1100     * Thread-local storage used to carry caller permissions over through
1101     * indirect content-provider access.
1102     */
1103    private class Identity {
1104        public final IBinder token;
1105        public final int pid;
1106        public final int uid;
1107
1108        Identity(IBinder _token, int _pid, int _uid) {
1109            token = _token;
1110            pid = _pid;
1111            uid = _uid;
1112        }
1113    }
1114
1115    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1116
1117    /**
1118     * All information we have collected about the runtime performance of
1119     * any user id that can impact battery performance.
1120     */
1121    final BatteryStatsService mBatteryStatsService;
1122
1123    /**
1124     * Information about component usage
1125     */
1126    UsageStatsManagerInternal mUsageStatsService;
1127
1128    /**
1129     * Access to DeviceIdleController service.
1130     */
1131    DeviceIdleController.LocalService mLocalDeviceIdleController;
1132
1133    /**
1134     * Information about and control over application operations
1135     */
1136    final AppOpsService mAppOpsService;
1137
1138    /**
1139     * Current configuration information.  HistoryRecord objects are given
1140     * a reference to this object to indicate which configuration they are
1141     * currently running in, so this object must be kept immutable.
1142     */
1143    Configuration mConfiguration = new Configuration();
1144
1145    /**
1146     * Current sequencing integer of the configuration, for skipping old
1147     * configurations.
1148     */
1149    int mConfigurationSeq = 0;
1150
1151    boolean mSuppressResizeConfigChanges = false;
1152
1153    /**
1154     * Hardware-reported OpenGLES version.
1155     */
1156    final int GL_ES_VERSION;
1157
1158    /**
1159     * List of initialization arguments to pass to all processes when binding applications to them.
1160     * For example, references to the commonly used services.
1161     */
1162    HashMap<String, IBinder> mAppBindArgs;
1163    HashMap<String, IBinder> mIsolatedAppBindArgs;
1164
1165    /**
1166     * Temporary to avoid allocations.  Protected by main lock.
1167     */
1168    final StringBuilder mStringBuilder = new StringBuilder(256);
1169
1170    /**
1171     * Used to control how we initialize the service.
1172     */
1173    ComponentName mTopComponent;
1174    String mTopAction = Intent.ACTION_MAIN;
1175    String mTopData;
1176
1177    volatile boolean mProcessesReady = false;
1178    volatile boolean mSystemReady = false;
1179    volatile boolean mOnBattery = false;
1180    volatile int mFactoryTest;
1181
1182    @GuardedBy("this") boolean mBooting = false;
1183    @GuardedBy("this") boolean mCallFinishBooting = false;
1184    @GuardedBy("this") boolean mBootAnimationComplete = false;
1185    @GuardedBy("this") boolean mLaunchWarningShown = false;
1186    @GuardedBy("this") boolean mCheckedForSetup = false;
1187
1188    Context mContext;
1189
1190    /**
1191     * The time at which we will allow normal application switches again,
1192     * after a call to {@link #stopAppSwitches()}.
1193     */
1194    long mAppSwitchesAllowedTime;
1195
1196    /**
1197     * This is set to true after the first switch after mAppSwitchesAllowedTime
1198     * is set; any switches after that will clear the time.
1199     */
1200    boolean mDidAppSwitch;
1201
1202    /**
1203     * Last time (in realtime) at which we checked for power usage.
1204     */
1205    long mLastPowerCheckRealtime;
1206
1207    /**
1208     * Last time (in uptime) at which we checked for power usage.
1209     */
1210    long mLastPowerCheckUptime;
1211
1212    /**
1213     * Set while we are wanting to sleep, to prevent any
1214     * activities from being started/resumed.
1215     */
1216    private boolean mSleeping = false;
1217
1218    /**
1219     * The process state used for processes that are running the top activities.
1220     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1221     */
1222    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1223
1224    /**
1225     * Set while we are running a voice interaction.  This overrides
1226     * sleeping while it is active.
1227     */
1228    private IVoiceInteractionSession mRunningVoice;
1229
1230    /**
1231     * For some direct access we need to power manager.
1232     */
1233    PowerManagerInternal mLocalPowerManager;
1234
1235    /**
1236     * We want to hold a wake lock while running a voice interaction session, since
1237     * this may happen with the screen off and we need to keep the CPU running to
1238     * be able to continue to interact with the user.
1239     */
1240    PowerManager.WakeLock mVoiceWakeLock;
1241
1242    /**
1243     * State of external calls telling us if the device is awake or asleep.
1244     */
1245    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1246
1247    /**
1248     * A list of tokens that cause the top activity to be put to sleep.
1249     * They are used by components that may hide and block interaction with underlying
1250     * activities.
1251     */
1252    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1253
1254    static final int LOCK_SCREEN_HIDDEN = 0;
1255    static final int LOCK_SCREEN_LEAVING = 1;
1256    static final int LOCK_SCREEN_SHOWN = 2;
1257    /**
1258     * State of external call telling us if the lock screen is shown.
1259     */
1260    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1261
1262    /**
1263     * Set if we are shutting down the system, similar to sleeping.
1264     */
1265    boolean mShuttingDown = false;
1266
1267    /**
1268     * Current sequence id for oom_adj computation traversal.
1269     */
1270    int mAdjSeq = 0;
1271
1272    /**
1273     * Current sequence id for process LRU updating.
1274     */
1275    int mLruSeq = 0;
1276
1277    /**
1278     * Keep track of the non-cached/empty process we last found, to help
1279     * determine how to distribute cached/empty processes next time.
1280     */
1281    int mNumNonCachedProcs = 0;
1282
1283    /**
1284     * Keep track of the number of cached hidden procs, to balance oom adj
1285     * distribution between those and empty procs.
1286     */
1287    int mNumCachedHiddenProcs = 0;
1288
1289    /**
1290     * Keep track of the number of service processes we last found, to
1291     * determine on the next iteration which should be B services.
1292     */
1293    int mNumServiceProcs = 0;
1294    int mNewNumAServiceProcs = 0;
1295    int mNewNumServiceProcs = 0;
1296
1297    /**
1298     * Allow the current computed overall memory level of the system to go down?
1299     * This is set to false when we are killing processes for reasons other than
1300     * memory management, so that the now smaller process list will not be taken as
1301     * an indication that memory is tighter.
1302     */
1303    boolean mAllowLowerMemLevel = false;
1304
1305    /**
1306     * The last computed memory level, for holding when we are in a state that
1307     * processes are going away for other reasons.
1308     */
1309    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1310
1311    /**
1312     * The last total number of process we have, to determine if changes actually look
1313     * like a shrinking number of process due to lower RAM.
1314     */
1315    int mLastNumProcesses;
1316
1317    /**
1318     * The uptime of the last time we performed idle maintenance.
1319     */
1320    long mLastIdleTime = SystemClock.uptimeMillis();
1321
1322    /**
1323     * Total time spent with RAM that has been added in the past since the last idle time.
1324     */
1325    long mLowRamTimeSinceLastIdle = 0;
1326
1327    /**
1328     * If RAM is currently low, when that horrible situation started.
1329     */
1330    long mLowRamStartTime = 0;
1331
1332    /**
1333     * For reporting to battery stats the current top application.
1334     */
1335    private String mCurResumedPackage = null;
1336    private int mCurResumedUid = -1;
1337
1338    /**
1339     * For reporting to battery stats the apps currently running foreground
1340     * service.  The ProcessMap is package/uid tuples; each of these contain
1341     * an array of the currently foreground processes.
1342     */
1343    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1344            = new ProcessMap<ArrayList<ProcessRecord>>();
1345
1346    /**
1347     * This is set if we had to do a delayed dexopt of an app before launching
1348     * it, to increase the ANR timeouts in that case.
1349     */
1350    boolean mDidDexOpt;
1351
1352    /**
1353     * Set if the systemServer made a call to enterSafeMode.
1354     */
1355    boolean mSafeMode;
1356
1357    /**
1358     * If true, we are running under a test environment so will sample PSS from processes
1359     * much more rapidly to try to collect better data when the tests are rapidly
1360     * running through apps.
1361     */
1362    boolean mTestPssMode = false;
1363
1364    String mDebugApp = null;
1365    boolean mWaitForDebugger = false;
1366    boolean mDebugTransient = false;
1367    String mOrigDebugApp = null;
1368    boolean mOrigWaitForDebugger = false;
1369    boolean mAlwaysFinishActivities = false;
1370    boolean mLenientBackgroundCheck = false;
1371    boolean mForceResizableActivities;
1372    boolean mSupportsMultiWindow;
1373    boolean mSupportsFreeformWindowManagement;
1374    boolean mSupportsPictureInPicture;
1375    boolean mSupportsLeanbackOnly;
1376    Rect mDefaultPinnedStackBounds;
1377    IActivityController mController = null;
1378    boolean mControllerIsAMonkey = false;
1379    String mProfileApp = null;
1380    ProcessRecord mProfileProc = null;
1381    String mProfileFile;
1382    ParcelFileDescriptor mProfileFd;
1383    int mSamplingInterval = 0;
1384    boolean mAutoStopProfiler = false;
1385    int mProfileType = 0;
1386    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1387    String mMemWatchDumpProcName;
1388    String mMemWatchDumpFile;
1389    int mMemWatchDumpPid;
1390    int mMemWatchDumpUid;
1391    String mTrackAllocationApp = null;
1392    String mNativeDebuggingApp = null;
1393
1394    final long[] mTmpLong = new long[2];
1395
1396    static final class ProcessChangeItem {
1397        static final int CHANGE_ACTIVITIES = 1<<0;
1398        static final int CHANGE_PROCESS_STATE = 1<<1;
1399        int changes;
1400        int uid;
1401        int pid;
1402        int processState;
1403        boolean foregroundActivities;
1404    }
1405
1406    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1407    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1408
1409    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1410    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1411
1412    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1413    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1414
1415    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1416    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1417
1418    /**
1419     * Runtime CPU use collection thread.  This object's lock is used to
1420     * perform synchronization with the thread (notifying it to run).
1421     */
1422    final Thread mProcessCpuThread;
1423
1424    /**
1425     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1426     * Must acquire this object's lock when accessing it.
1427     * NOTE: this lock will be held while doing long operations (trawling
1428     * through all processes in /proc), so it should never be acquired by
1429     * any critical paths such as when holding the main activity manager lock.
1430     */
1431    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1432            MONITOR_THREAD_CPU_USAGE);
1433    final AtomicLong mLastCpuTime = new AtomicLong(0);
1434    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1435
1436    long mLastWriteTime = 0;
1437
1438    /**
1439     * Used to retain an update lock when the foreground activity is in
1440     * immersive mode.
1441     */
1442    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1443
1444    /**
1445     * Set to true after the system has finished booting.
1446     */
1447    boolean mBooted = false;
1448
1449    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1450    int mProcessLimitOverride = -1;
1451
1452    WindowManagerService mWindowManager;
1453    final ActivityThread mSystemThread;
1454
1455    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1456        final ProcessRecord mApp;
1457        final int mPid;
1458        final IApplicationThread mAppThread;
1459
1460        AppDeathRecipient(ProcessRecord app, int pid,
1461                IApplicationThread thread) {
1462            if (DEBUG_ALL) Slog.v(
1463                TAG, "New death recipient " + this
1464                + " for thread " + thread.asBinder());
1465            mApp = app;
1466            mPid = pid;
1467            mAppThread = thread;
1468        }
1469
1470        @Override
1471        public void binderDied() {
1472            if (DEBUG_ALL) Slog.v(
1473                TAG, "Death received in " + this
1474                + " for thread " + mAppThread.asBinder());
1475            synchronized(ActivityManagerService.this) {
1476                appDiedLocked(mApp, mPid, mAppThread, true);
1477            }
1478        }
1479    }
1480
1481    static final int SHOW_ERROR_UI_MSG = 1;
1482    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1483    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1484    static final int UPDATE_CONFIGURATION_MSG = 4;
1485    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1486    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1487    static final int SERVICE_TIMEOUT_MSG = 12;
1488    static final int UPDATE_TIME_ZONE = 13;
1489    static final int SHOW_UID_ERROR_UI_MSG = 14;
1490    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1491    static final int PROC_START_TIMEOUT_MSG = 20;
1492    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1493    static final int KILL_APPLICATION_MSG = 22;
1494    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1495    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1496    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1497    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1498    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1499    static final int CLEAR_DNS_CACHE_MSG = 28;
1500    static final int UPDATE_HTTP_PROXY_MSG = 29;
1501    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1502    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1503    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1504    static final int REPORT_MEM_USAGE_MSG = 33;
1505    static final int REPORT_USER_SWITCH_MSG = 34;
1506    static final int CONTINUE_USER_SWITCH_MSG = 35;
1507    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1508    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1509    static final int PERSIST_URI_GRANTS_MSG = 38;
1510    static final int REQUEST_ALL_PSS_MSG = 39;
1511    static final int START_PROFILES_MSG = 40;
1512    static final int UPDATE_TIME = 41;
1513    static final int SYSTEM_USER_START_MSG = 42;
1514    static final int SYSTEM_USER_CURRENT_MSG = 43;
1515    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1516    static final int FINISH_BOOTING_MSG = 45;
1517    static final int START_USER_SWITCH_UI_MSG = 46;
1518    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1519    static final int DISMISS_DIALOG_UI_MSG = 48;
1520    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1521    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1522    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1523    static final int DELETE_DUMPHEAP_MSG = 52;
1524    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1525    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1526    static final int REPORT_TIME_TRACKER_MSG = 55;
1527    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1528    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1529    static final int APP_BOOST_DEACTIVATE_MSG = 58;
1530    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1531    static final int IDLE_UIDS_MSG = 60;
1532    static final int SYSTEM_USER_UNLOCK_MSG = 61;
1533    static final int LOG_STACK_STATE = 62;
1534    static final int VR_MODE_CHANGE_MSG = 63;
1535    static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1536    static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1537    static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1538    static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
1539    static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
1540    static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
1541    static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 70;
1542
1543    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1544    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1545    static final int FIRST_COMPAT_MODE_MSG = 300;
1546    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1547
1548    static ServiceThread sKillThread = null;
1549    static KillHandler sKillHandler = null;
1550
1551    CompatModeDialog mCompatModeDialog;
1552    UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1553    long mLastMemUsageReportTime = 0;
1554
1555    /**
1556     * Flag whether the current user is a "monkey", i.e. whether
1557     * the UI is driven by a UI automation tool.
1558     */
1559    private boolean mUserIsMonkey;
1560
1561    /** Flag whether the device has a Recents UI */
1562    boolean mHasRecents;
1563
1564    /** The dimensions of the thumbnails in the Recents UI. */
1565    int mThumbnailWidth;
1566    int mThumbnailHeight;
1567    float mFullscreenThumbnailScale;
1568
1569    final ServiceThread mHandlerThread;
1570    final MainHandler mHandler;
1571    final UiHandler mUiHandler;
1572
1573    PackageManagerInternal mPackageManagerInt;
1574
1575    // VoiceInteraction session ID that changes for each new request except when
1576    // being called for multiwindow assist in a single session.
1577    private int mViSessionId = 1000;
1578
1579    final class KillHandler extends Handler {
1580        static final int KILL_PROCESS_GROUP_MSG = 4000;
1581
1582        public KillHandler(Looper looper) {
1583            super(looper, null, true);
1584        }
1585
1586        @Override
1587        public void handleMessage(Message msg) {
1588            switch (msg.what) {
1589                case KILL_PROCESS_GROUP_MSG:
1590                {
1591                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1592                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1593                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1594                }
1595                break;
1596
1597                default:
1598                    super.handleMessage(msg);
1599            }
1600        }
1601    }
1602
1603    final class UiHandler extends Handler {
1604        public UiHandler() {
1605            super(com.android.server.UiThread.get().getLooper(), null, true);
1606        }
1607
1608        @Override
1609        public void handleMessage(Message msg) {
1610            switch (msg.what) {
1611            case SHOW_ERROR_UI_MSG: {
1612                mAppErrors.handleShowAppErrorUi(msg);
1613                ensureBootCompleted();
1614            } break;
1615            case SHOW_NOT_RESPONDING_UI_MSG: {
1616                mAppErrors.handleShowAnrUi(msg);
1617                ensureBootCompleted();
1618            } break;
1619            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1620                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1621                synchronized (ActivityManagerService.this) {
1622                    ProcessRecord proc = (ProcessRecord) data.get("app");
1623                    if (proc == null) {
1624                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1625                        break;
1626                    }
1627                    if (proc.crashDialog != null) {
1628                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1629                        return;
1630                    }
1631                    AppErrorResult res = (AppErrorResult) data.get("result");
1632                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1633                        Dialog d = new StrictModeViolationDialog(mContext,
1634                                ActivityManagerService.this, res, proc);
1635                        d.show();
1636                        proc.crashDialog = d;
1637                    } else {
1638                        // The device is asleep, so just pretend that the user
1639                        // saw a crash dialog and hit "force quit".
1640                        res.set(0);
1641                    }
1642                }
1643                ensureBootCompleted();
1644            } break;
1645            case SHOW_FACTORY_ERROR_UI_MSG: {
1646                Dialog d = new FactoryErrorDialog(
1647                    mContext, msg.getData().getCharSequence("msg"));
1648                d.show();
1649                ensureBootCompleted();
1650            } break;
1651            case WAIT_FOR_DEBUGGER_UI_MSG: {
1652                synchronized (ActivityManagerService.this) {
1653                    ProcessRecord app = (ProcessRecord)msg.obj;
1654                    if (msg.arg1 != 0) {
1655                        if (!app.waitedForDebugger) {
1656                            Dialog d = new AppWaitingForDebuggerDialog(
1657                                    ActivityManagerService.this,
1658                                    mContext, app);
1659                            app.waitDialog = d;
1660                            app.waitedForDebugger = true;
1661                            d.show();
1662                        }
1663                    } else {
1664                        if (app.waitDialog != null) {
1665                            app.waitDialog.dismiss();
1666                            app.waitDialog = null;
1667                        }
1668                    }
1669                }
1670            } break;
1671            case SHOW_UID_ERROR_UI_MSG: {
1672                if (mShowDialogs) {
1673                    AlertDialog d = new BaseErrorDialog(mContext);
1674                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1675                    d.setCancelable(false);
1676                    d.setTitle(mContext.getText(R.string.android_system_label));
1677                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1678                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1679                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1680                    d.show();
1681                }
1682            } break;
1683            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1684                if (mShowDialogs) {
1685                    AlertDialog d = new BaseErrorDialog(mContext);
1686                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1687                    d.setCancelable(false);
1688                    d.setTitle(mContext.getText(R.string.android_system_label));
1689                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1690                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1691                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1692                    d.show();
1693                }
1694            } break;
1695            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1696                synchronized (ActivityManagerService.this) {
1697                    ActivityRecord ar = (ActivityRecord) msg.obj;
1698                    if (mCompatModeDialog != null) {
1699                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1700                                ar.info.applicationInfo.packageName)) {
1701                            return;
1702                        }
1703                        mCompatModeDialog.dismiss();
1704                        mCompatModeDialog = null;
1705                    }
1706                    if (ar != null && false) {
1707                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1708                                ar.packageName)) {
1709                            int mode = mCompatModePackages.computeCompatModeLocked(
1710                                    ar.info.applicationInfo);
1711                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1712                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1713                                mCompatModeDialog = new CompatModeDialog(
1714                                        ActivityManagerService.this, mContext,
1715                                        ar.info.applicationInfo);
1716                                mCompatModeDialog.show();
1717                            }
1718                        }
1719                    }
1720                }
1721                break;
1722            }
1723            case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1724                synchronized (ActivityManagerService.this) {
1725                    final ActivityRecord ar = (ActivityRecord) msg.obj;
1726                    if (mUnsupportedDisplaySizeDialog != null) {
1727                        mUnsupportedDisplaySizeDialog.dismiss();
1728                        mUnsupportedDisplaySizeDialog = null;
1729                    }
1730                    if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1731                            ar.packageName)) {
1732                        mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1733                                ActivityManagerService.this, mContext, ar.info.applicationInfo);
1734                        mUnsupportedDisplaySizeDialog.show();
1735                    }
1736                }
1737                break;
1738            }
1739            case START_USER_SWITCH_UI_MSG: {
1740                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1741                break;
1742            }
1743            case DISMISS_DIALOG_UI_MSG: {
1744                final Dialog d = (Dialog) msg.obj;
1745                d.dismiss();
1746                break;
1747            }
1748            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1749                dispatchProcessesChanged();
1750                break;
1751            }
1752            case DISPATCH_PROCESS_DIED_UI_MSG: {
1753                final int pid = msg.arg1;
1754                final int uid = msg.arg2;
1755                dispatchProcessDied(pid, uid);
1756                break;
1757            }
1758            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1759                dispatchUidsChanged();
1760            } break;
1761            }
1762        }
1763    }
1764
1765    final class MainHandler extends Handler {
1766        public MainHandler(Looper looper) {
1767            super(looper, null, true);
1768        }
1769
1770        @Override
1771        public void handleMessage(Message msg) {
1772            switch (msg.what) {
1773            case UPDATE_CONFIGURATION_MSG: {
1774                final ContentResolver resolver = mContext.getContentResolver();
1775                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1776                        msg.arg1);
1777            } break;
1778            case GC_BACKGROUND_PROCESSES_MSG: {
1779                synchronized (ActivityManagerService.this) {
1780                    performAppGcsIfAppropriateLocked();
1781                }
1782            } break;
1783            case SERVICE_TIMEOUT_MSG: {
1784                if (mDidDexOpt) {
1785                    mDidDexOpt = false;
1786                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1787                    nmsg.obj = msg.obj;
1788                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1789                    return;
1790                }
1791                mServices.serviceTimeout((ProcessRecord)msg.obj);
1792            } break;
1793            case UPDATE_TIME_ZONE: {
1794                synchronized (ActivityManagerService.this) {
1795                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1796                        ProcessRecord r = mLruProcesses.get(i);
1797                        if (r.thread != null) {
1798                            try {
1799                                r.thread.updateTimeZone();
1800                            } catch (RemoteException ex) {
1801                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1802                            }
1803                        }
1804                    }
1805                }
1806            } break;
1807            case CLEAR_DNS_CACHE_MSG: {
1808                synchronized (ActivityManagerService.this) {
1809                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1810                        ProcessRecord r = mLruProcesses.get(i);
1811                        if (r.thread != null) {
1812                            try {
1813                                r.thread.clearDnsCache();
1814                            } catch (RemoteException ex) {
1815                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1816                            }
1817                        }
1818                    }
1819                }
1820            } break;
1821            case UPDATE_HTTP_PROXY_MSG: {
1822                ProxyInfo proxy = (ProxyInfo)msg.obj;
1823                String host = "";
1824                String port = "";
1825                String exclList = "";
1826                Uri pacFileUrl = Uri.EMPTY;
1827                if (proxy != null) {
1828                    host = proxy.getHost();
1829                    port = Integer.toString(proxy.getPort());
1830                    exclList = proxy.getExclusionListAsString();
1831                    pacFileUrl = proxy.getPacFileUrl();
1832                }
1833                synchronized (ActivityManagerService.this) {
1834                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1835                        ProcessRecord r = mLruProcesses.get(i);
1836                        if (r.thread != null) {
1837                            try {
1838                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1839                            } catch (RemoteException ex) {
1840                                Slog.w(TAG, "Failed to update http proxy for: " +
1841                                        r.info.processName);
1842                            }
1843                        }
1844                    }
1845                }
1846            } break;
1847            case PROC_START_TIMEOUT_MSG: {
1848                if (mDidDexOpt) {
1849                    mDidDexOpt = false;
1850                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1851                    nmsg.obj = msg.obj;
1852                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1853                    return;
1854                }
1855                ProcessRecord app = (ProcessRecord)msg.obj;
1856                synchronized (ActivityManagerService.this) {
1857                    processStartTimedOutLocked(app);
1858                }
1859            } break;
1860            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1861                ProcessRecord app = (ProcessRecord)msg.obj;
1862                synchronized (ActivityManagerService.this) {
1863                    processContentProviderPublishTimedOutLocked(app);
1864                }
1865            } break;
1866            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1867                synchronized (ActivityManagerService.this) {
1868                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1869                }
1870            } break;
1871            case KILL_APPLICATION_MSG: {
1872                synchronized (ActivityManagerService.this) {
1873                    final int appId = msg.arg1;
1874                    final int userId = msg.arg2;
1875                    Bundle bundle = (Bundle)msg.obj;
1876                    String pkg = bundle.getString("pkg");
1877                    String reason = bundle.getString("reason");
1878                    forceStopPackageLocked(pkg, appId, false, false, true, false,
1879                            false, userId, reason);
1880                }
1881            } break;
1882            case FINALIZE_PENDING_INTENT_MSG: {
1883                ((PendingIntentRecord)msg.obj).completeFinalize();
1884            } break;
1885            case POST_HEAVY_NOTIFICATION_MSG: {
1886                INotificationManager inm = NotificationManager.getService();
1887                if (inm == null) {
1888                    return;
1889                }
1890
1891                ActivityRecord root = (ActivityRecord)msg.obj;
1892                ProcessRecord process = root.app;
1893                if (process == null) {
1894                    return;
1895                }
1896
1897                try {
1898                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1899                    String text = mContext.getString(R.string.heavy_weight_notification,
1900                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1901                    Notification notification = new Notification.Builder(context)
1902                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1903                            .setWhen(0)
1904                            .setOngoing(true)
1905                            .setTicker(text)
1906                            .setColor(mContext.getColor(
1907                                    com.android.internal.R.color.system_notification_accent_color))
1908                            .setContentTitle(text)
1909                            .setContentText(
1910                                    mContext.getText(R.string.heavy_weight_notification_detail))
1911                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1912                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1913                                    new UserHandle(root.userId)))
1914                            .build();
1915                    try {
1916                        int[] outId = new int[1];
1917                        inm.enqueueNotificationWithTag("android", "android", null,
1918                                R.string.heavy_weight_notification,
1919                                notification, outId, root.userId);
1920                    } catch (RuntimeException e) {
1921                        Slog.w(ActivityManagerService.TAG,
1922                                "Error showing notification for heavy-weight app", e);
1923                    } catch (RemoteException e) {
1924                    }
1925                } catch (NameNotFoundException e) {
1926                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1927                }
1928            } break;
1929            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1930                INotificationManager inm = NotificationManager.getService();
1931                if (inm == null) {
1932                    return;
1933                }
1934                try {
1935                    inm.cancelNotificationWithTag("android", null,
1936                            R.string.heavy_weight_notification,  msg.arg1);
1937                } catch (RuntimeException e) {
1938                    Slog.w(ActivityManagerService.TAG,
1939                            "Error canceling notification for service", e);
1940                } catch (RemoteException e) {
1941                }
1942            } break;
1943            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1944                synchronized (ActivityManagerService.this) {
1945                    checkExcessivePowerUsageLocked(true);
1946                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1947                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1948                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1949                }
1950            } break;
1951            case REPORT_MEM_USAGE_MSG: {
1952                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1953                Thread thread = new Thread() {
1954                    @Override public void run() {
1955                        reportMemUsage(memInfos);
1956                    }
1957                };
1958                thread.start();
1959                break;
1960            }
1961            case REPORT_USER_SWITCH_MSG: {
1962                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1963                break;
1964            }
1965            case CONTINUE_USER_SWITCH_MSG: {
1966                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1967                break;
1968            }
1969            case USER_SWITCH_TIMEOUT_MSG: {
1970                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1971                break;
1972            }
1973            case IMMERSIVE_MODE_LOCK_MSG: {
1974                final boolean nextState = (msg.arg1 != 0);
1975                if (mUpdateLock.isHeld() != nextState) {
1976                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1977                            "Applying new update lock state '" + nextState
1978                            + "' for " + (ActivityRecord)msg.obj);
1979                    if (nextState) {
1980                        mUpdateLock.acquire();
1981                    } else {
1982                        mUpdateLock.release();
1983                    }
1984                }
1985                break;
1986            }
1987            case PERSIST_URI_GRANTS_MSG: {
1988                writeGrantedUriPermissions();
1989                break;
1990            }
1991            case REQUEST_ALL_PSS_MSG: {
1992                synchronized (ActivityManagerService.this) {
1993                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1994                }
1995                break;
1996            }
1997            case START_PROFILES_MSG: {
1998                synchronized (ActivityManagerService.this) {
1999                    mUserController.startProfilesLocked();
2000                }
2001                break;
2002            }
2003            case UPDATE_TIME: {
2004                synchronized (ActivityManagerService.this) {
2005                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2006                        ProcessRecord r = mLruProcesses.get(i);
2007                        if (r.thread != null) {
2008                            try {
2009                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
2010                            } catch (RemoteException ex) {
2011                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
2012                            }
2013                        }
2014                    }
2015                }
2016                break;
2017            }
2018            case SYSTEM_USER_START_MSG: {
2019                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2020                        Integer.toString(msg.arg1), msg.arg1);
2021                mSystemServiceManager.startUser(msg.arg1);
2022                break;
2023            }
2024            case SYSTEM_USER_UNLOCK_MSG: {
2025                final int userId = msg.arg1;
2026                mSystemServiceManager.unlockUser(userId);
2027                synchronized (ActivityManagerService.this) {
2028                    mRecentTasks.loadUserRecentsLocked(userId);
2029                }
2030                if (userId == UserHandle.USER_SYSTEM) {
2031                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2032                }
2033                installEncryptionUnawareProviders(userId);
2034                mUserController.finishUserUnlocked((UserState) msg.obj);
2035                break;
2036            }
2037            case SYSTEM_USER_CURRENT_MSG: {
2038                mBatteryStatsService.noteEvent(
2039                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2040                        Integer.toString(msg.arg2), msg.arg2);
2041                mBatteryStatsService.noteEvent(
2042                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2043                        Integer.toString(msg.arg1), msg.arg1);
2044                mSystemServiceManager.switchUser(msg.arg1);
2045                break;
2046            }
2047            case ENTER_ANIMATION_COMPLETE_MSG: {
2048                synchronized (ActivityManagerService.this) {
2049                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2050                    if (r != null && r.app != null && r.app.thread != null) {
2051                        try {
2052                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2053                        } catch (RemoteException e) {
2054                        }
2055                    }
2056                }
2057                break;
2058            }
2059            case FINISH_BOOTING_MSG: {
2060                if (msg.arg1 != 0) {
2061                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2062                    finishBooting();
2063                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2064                }
2065                if (msg.arg2 != 0) {
2066                    enableScreenAfterBoot();
2067                }
2068                break;
2069            }
2070            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2071                try {
2072                    Locale l = (Locale) msg.obj;
2073                    IBinder service = ServiceManager.getService("mount");
2074                    IMountService mountService = IMountService.Stub.asInterface(service);
2075                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2076                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2077                } catch (RemoteException e) {
2078                    Log.e(TAG, "Error storing locale for decryption UI", e);
2079                }
2080                break;
2081            }
2082            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
2083                synchronized (ActivityManagerService.this) {
2084                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2085                        try {
2086                            // Make a one-way callback to the listener
2087                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
2088                        } catch (RemoteException e){
2089                            // Handled by the RemoteCallbackList
2090                        }
2091                    }
2092                    mTaskStackListeners.finishBroadcast();
2093                }
2094                break;
2095            }
2096            case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
2097                synchronized (ActivityManagerService.this) {
2098                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2099                        try {
2100                            // Make a one-way callback to the listener
2101                            mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
2102                        } catch (RemoteException e){
2103                            // Handled by the RemoteCallbackList
2104                        }
2105                    }
2106                    mTaskStackListeners.finishBroadcast();
2107                }
2108                break;
2109            }
2110            case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
2111                synchronized (ActivityManagerService.this) {
2112                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2113                        try {
2114                            // Make a one-way callback to the listener
2115                            mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
2116                        } catch (RemoteException e){
2117                            // Handled by the RemoteCallbackList
2118                        }
2119                    }
2120                    mTaskStackListeners.finishBroadcast();
2121                }
2122                break;
2123            }
2124            case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2125                synchronized (ActivityManagerService.this) {
2126                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2127                        try {
2128                            // Make a one-way callback to the listener
2129                            mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2130                        } catch (RemoteException e){
2131                            // Handled by the RemoteCallbackList
2132                        }
2133                    }
2134                    mTaskStackListeners.finishBroadcast();
2135                }
2136                break;
2137            }
2138            case NOTIFY_FORCED_RESIZABLE_MSG: {
2139                synchronized (ActivityManagerService.this) {
2140                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2141                        try {
2142                            // Make a one-way callback to the listener
2143                            mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
2144                                    (String) msg.obj, msg.arg1);
2145                        } catch (RemoteException e){
2146                            // Handled by the RemoteCallbackList
2147                        }
2148                    }
2149                    mTaskStackListeners.finishBroadcast();
2150                }
2151                break;
2152            }
2153                case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
2154                    synchronized (ActivityManagerService.this) {
2155                        for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2156                            try {
2157                                // Make a one-way callback to the listener
2158                                mTaskStackListeners.getBroadcastItem(i)
2159                                        .onActivityDismissingDockedStack();
2160                            } catch (RemoteException e){
2161                                // Handled by the RemoteCallbackList
2162                            }
2163                        }
2164                        mTaskStackListeners.finishBroadcast();
2165                    }
2166                    break;
2167                }
2168            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2169                final int uid = msg.arg1;
2170                final byte[] firstPacket = (byte[]) msg.obj;
2171
2172                synchronized (mPidsSelfLocked) {
2173                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2174                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2175                        if (p.uid == uid) {
2176                            try {
2177                                p.thread.notifyCleartextNetwork(firstPacket);
2178                            } catch (RemoteException ignored) {
2179                            }
2180                        }
2181                    }
2182                }
2183                break;
2184            }
2185            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2186                final String procName;
2187                final int uid;
2188                final long memLimit;
2189                final String reportPackage;
2190                synchronized (ActivityManagerService.this) {
2191                    procName = mMemWatchDumpProcName;
2192                    uid = mMemWatchDumpUid;
2193                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2194                    if (val == null) {
2195                        val = mMemWatchProcesses.get(procName, 0);
2196                    }
2197                    if (val != null) {
2198                        memLimit = val.first;
2199                        reportPackage = val.second;
2200                    } else {
2201                        memLimit = 0;
2202                        reportPackage = null;
2203                    }
2204                }
2205                if (procName == null) {
2206                    return;
2207                }
2208
2209                if (DEBUG_PSS) Slog.d(TAG_PSS,
2210                        "Showing dump heap notification from " + procName + "/" + uid);
2211
2212                INotificationManager inm = NotificationManager.getService();
2213                if (inm == null) {
2214                    return;
2215                }
2216
2217                String text = mContext.getString(R.string.dump_heap_notification, procName);
2218
2219
2220                Intent deleteIntent = new Intent();
2221                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2222                Intent intent = new Intent();
2223                intent.setClassName("android", DumpHeapActivity.class.getName());
2224                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2225                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2226                if (reportPackage != null) {
2227                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2228                }
2229                int userId = UserHandle.getUserId(uid);
2230                Notification notification = new Notification.Builder(mContext)
2231                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2232                        .setWhen(0)
2233                        .setOngoing(true)
2234                        .setAutoCancel(true)
2235                        .setTicker(text)
2236                        .setColor(mContext.getColor(
2237                                com.android.internal.R.color.system_notification_accent_color))
2238                        .setContentTitle(text)
2239                        .setContentText(
2240                                mContext.getText(R.string.dump_heap_notification_detail))
2241                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2242                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2243                                new UserHandle(userId)))
2244                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2245                                deleteIntent, 0, UserHandle.SYSTEM))
2246                        .build();
2247
2248                try {
2249                    int[] outId = new int[1];
2250                    inm.enqueueNotificationWithTag("android", "android", null,
2251                            R.string.dump_heap_notification,
2252                            notification, outId, userId);
2253                } catch (RuntimeException e) {
2254                    Slog.w(ActivityManagerService.TAG,
2255                            "Error showing notification for dump heap", e);
2256                } catch (RemoteException e) {
2257                }
2258            } break;
2259            case DELETE_DUMPHEAP_MSG: {
2260                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2261                        DumpHeapActivity.JAVA_URI,
2262                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2263                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2264                        UserHandle.myUserId());
2265                synchronized (ActivityManagerService.this) {
2266                    mMemWatchDumpFile = null;
2267                    mMemWatchDumpProcName = null;
2268                    mMemWatchDumpPid = -1;
2269                    mMemWatchDumpUid = -1;
2270                }
2271            } break;
2272            case FOREGROUND_PROFILE_CHANGED_MSG: {
2273                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2274            } break;
2275            case REPORT_TIME_TRACKER_MSG: {
2276                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2277                tracker.deliverResult(mContext);
2278            } break;
2279            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2280                mUserController.dispatchUserSwitchComplete(msg.arg1);
2281            } break;
2282            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2283                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2284                try {
2285                    connection.shutdown();
2286                } catch (RemoteException e) {
2287                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2288                }
2289                // Only a UiAutomation can set this flag and now that
2290                // it is finished we make sure it is reset to its default.
2291                mUserIsMonkey = false;
2292            } break;
2293            case APP_BOOST_DEACTIVATE_MSG: {
2294                synchronized(ActivityManagerService.this) {
2295                    if (mIsBoosted) {
2296                        if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2297                            nativeMigrateFromBoost();
2298                            mIsBoosted = false;
2299                            mBoostStartTime = 0;
2300                        } else {
2301                            Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2302                            mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2303                        }
2304                    }
2305                }
2306            } break;
2307            case IDLE_UIDS_MSG: {
2308                idleUids();
2309            } break;
2310            case LOG_STACK_STATE: {
2311                synchronized (ActivityManagerService.this) {
2312                    mStackSupervisor.logStackState();
2313                }
2314            } break;
2315            case VR_MODE_CHANGE_MSG: {
2316                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2317                final ActivityRecord r = (ActivityRecord) msg.obj;
2318                boolean vrMode;
2319                ComponentName requestedPackage;
2320                ComponentName callingPackage;
2321                int userId;
2322                synchronized (ActivityManagerService.this) {
2323                    vrMode = r.requestedVrComponent != null;
2324                    requestedPackage = r.requestedVrComponent;
2325                    userId = r.userId;
2326                    callingPackage = r.info.getComponentName();
2327                    if (mInVrMode != vrMode) {
2328                        mInVrMode = vrMode;
2329                        mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2330                        if (r.app != null) {
2331                            ProcessRecord proc = r.app;
2332                            if (proc.vrThreadTid > 0) {
2333                                if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
2334                                    try {
2335                                        if (mInVrMode == true) {
2336                                            Process.setThreadScheduler(proc.vrThreadTid,
2337                                                Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
2338                                        } else {
2339                                            Process.setThreadScheduler(proc.vrThreadTid,
2340                                                Process.SCHED_OTHER, 0);
2341                                        }
2342                                    } catch (IllegalArgumentException e) {
2343                                        Slog.w(TAG, "Failed to set scheduling policy, thread does"
2344                                                + " not exist:\n" + e);
2345                                    }
2346                                }
2347                            }
2348                        }
2349                    }
2350                }
2351                vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2352            } break;
2353            case VR_MODE_APPLY_IF_NEEDED_MSG: {
2354                final ActivityRecord r = (ActivityRecord) msg.obj;
2355                final boolean needsVrMode = r != null && r.requestedVrComponent != null;
2356                if (needsVrMode) {
2357                    applyVrMode(msg.arg1 == 1, r.requestedVrComponent, r.userId,
2358                            r.info.getComponentName(), false);
2359                }
2360            } break;
2361            }
2362        }
2363    };
2364
2365    static final int COLLECT_PSS_BG_MSG = 1;
2366
2367    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2368        @Override
2369        public void handleMessage(Message msg) {
2370            switch (msg.what) {
2371            case COLLECT_PSS_BG_MSG: {
2372                long start = SystemClock.uptimeMillis();
2373                MemInfoReader memInfo = null;
2374                synchronized (ActivityManagerService.this) {
2375                    if (mFullPssPending) {
2376                        mFullPssPending = false;
2377                        memInfo = new MemInfoReader();
2378                    }
2379                }
2380                if (memInfo != null) {
2381                    updateCpuStatsNow();
2382                    long nativeTotalPss = 0;
2383                    final List<ProcessCpuTracker.Stats> stats;
2384                    synchronized (mProcessCpuTracker) {
2385                        stats = mProcessCpuTracker.getStats( (st)-> {
2386                            return st.vsize > 0 && st.uid < Process.FIRST_APPLICATION_UID;
2387                        });
2388                    }
2389                    final int N = stats.size();
2390                    for (int j = 0; j < N; j++) {
2391                        synchronized (mPidsSelfLocked) {
2392                            if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
2393                                // This is one of our own processes; skip it.
2394                                continue;
2395                            }
2396                        }
2397                        nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
2398                    }
2399                    memInfo.readMemInfo();
2400                    synchronized (ActivityManagerService.this) {
2401                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2402                                + (SystemClock.uptimeMillis()-start) + "ms");
2403                        final long cachedKb = memInfo.getCachedSizeKb();
2404                        final long freeKb = memInfo.getFreeSizeKb();
2405                        final long zramKb = memInfo.getZramTotalSizeKb();
2406                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2407                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2408                                kernelKb*1024, nativeTotalPss*1024);
2409                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2410                                nativeTotalPss);
2411                    }
2412                }
2413
2414                int num = 0;
2415                long[] tmp = new long[2];
2416                do {
2417                    ProcessRecord proc;
2418                    int procState;
2419                    int pid;
2420                    long lastPssTime;
2421                    synchronized (ActivityManagerService.this) {
2422                        if (mPendingPssProcesses.size() <= 0) {
2423                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2424                                    "Collected PSS of " + num + " processes in "
2425                                    + (SystemClock.uptimeMillis() - start) + "ms");
2426                            mPendingPssProcesses.clear();
2427                            return;
2428                        }
2429                        proc = mPendingPssProcesses.remove(0);
2430                        procState = proc.pssProcState;
2431                        lastPssTime = proc.lastPssTime;
2432                        if (proc.thread != null && procState == proc.setProcState
2433                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2434                                        < SystemClock.uptimeMillis()) {
2435                            pid = proc.pid;
2436                        } else {
2437                            proc = null;
2438                            pid = 0;
2439                        }
2440                    }
2441                    if (proc != null) {
2442                        long pss = Debug.getPss(pid, tmp, null);
2443                        synchronized (ActivityManagerService.this) {
2444                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2445                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2446                                num++;
2447                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2448                                        SystemClock.uptimeMillis());
2449                            }
2450                        }
2451                    }
2452                } while (true);
2453            }
2454            }
2455        }
2456    };
2457
2458    public void setSystemProcess() {
2459        try {
2460            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2461            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2462            ServiceManager.addService("meminfo", new MemBinder(this));
2463            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2464            ServiceManager.addService("dbinfo", new DbBinder(this));
2465            if (MONITOR_CPU_USAGE) {
2466                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2467            }
2468            ServiceManager.addService("permission", new PermissionController(this));
2469            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2470
2471            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2472                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2473            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2474
2475            synchronized (this) {
2476                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2477                app.persistent = true;
2478                app.pid = MY_PID;
2479                app.maxAdj = ProcessList.SYSTEM_ADJ;
2480                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2481                synchronized (mPidsSelfLocked) {
2482                    mPidsSelfLocked.put(app.pid, app);
2483                }
2484                updateLruProcessLocked(app, false, null);
2485                updateOomAdjLocked();
2486            }
2487        } catch (PackageManager.NameNotFoundException e) {
2488            throw new RuntimeException(
2489                    "Unable to find android system package", e);
2490        }
2491    }
2492
2493    public void setWindowManager(WindowManagerService wm) {
2494        mWindowManager = wm;
2495        mStackSupervisor.setWindowManager(wm);
2496        mActivityStarter.setWindowManager(wm);
2497    }
2498
2499    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2500        mUsageStatsService = usageStatsManager;
2501    }
2502
2503    public void startObservingNativeCrashes() {
2504        final NativeCrashListener ncl = new NativeCrashListener(this);
2505        ncl.start();
2506    }
2507
2508    public IAppOpsService getAppOpsService() {
2509        return mAppOpsService;
2510    }
2511
2512    static class MemBinder extends Binder {
2513        ActivityManagerService mActivityManagerService;
2514        MemBinder(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 meminfo from from pid="
2523                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2524                        + " without permission " + android.Manifest.permission.DUMP);
2525                return;
2526            }
2527
2528            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2529        }
2530    }
2531
2532    static class GraphicsBinder extends Binder {
2533        ActivityManagerService mActivityManagerService;
2534        GraphicsBinder(ActivityManagerService activityManagerService) {
2535            mActivityManagerService = activityManagerService;
2536        }
2537
2538        @Override
2539        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2540            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2541                    != PackageManager.PERMISSION_GRANTED) {
2542                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2543                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2544                        + " without permission " + android.Manifest.permission.DUMP);
2545                return;
2546            }
2547
2548            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2549        }
2550    }
2551
2552    static class DbBinder extends Binder {
2553        ActivityManagerService mActivityManagerService;
2554        DbBinder(ActivityManagerService activityManagerService) {
2555            mActivityManagerService = activityManagerService;
2556        }
2557
2558        @Override
2559        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2560            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2561                    != PackageManager.PERMISSION_GRANTED) {
2562                pw.println("Permission Denial: can't dump dbinfo from from pid="
2563                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2564                        + " without permission " + android.Manifest.permission.DUMP);
2565                return;
2566            }
2567
2568            mActivityManagerService.dumpDbInfo(fd, pw, args);
2569        }
2570    }
2571
2572    static class CpuBinder extends Binder {
2573        ActivityManagerService mActivityManagerService;
2574        CpuBinder(ActivityManagerService activityManagerService) {
2575            mActivityManagerService = activityManagerService;
2576        }
2577
2578        @Override
2579        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2580            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2581                    != PackageManager.PERMISSION_GRANTED) {
2582                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2583                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2584                        + " without permission " + android.Manifest.permission.DUMP);
2585                return;
2586            }
2587
2588            synchronized (mActivityManagerService.mProcessCpuTracker) {
2589                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2590                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2591                        SystemClock.uptimeMillis()));
2592            }
2593        }
2594    }
2595
2596    public static final class Lifecycle extends SystemService {
2597        private final ActivityManagerService mService;
2598
2599        public Lifecycle(Context context) {
2600            super(context);
2601            mService = new ActivityManagerService(context);
2602        }
2603
2604        @Override
2605        public void onStart() {
2606            mService.start();
2607        }
2608
2609        public ActivityManagerService getService() {
2610            return mService;
2611        }
2612    }
2613
2614    // Note: This method is invoked on the main thread but may need to attach various
2615    // handlers to other threads.  So take care to be explicit about the looper.
2616    public ActivityManagerService(Context systemContext) {
2617        mContext = systemContext;
2618        mFactoryTest = FactoryTest.getMode();
2619        mSystemThread = ActivityThread.currentActivityThread();
2620
2621        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2622
2623        mHandlerThread = new ServiceThread(TAG,
2624                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2625        mHandlerThread.start();
2626        mHandler = new MainHandler(mHandlerThread.getLooper());
2627        mUiHandler = new UiHandler();
2628
2629        /* static; one-time init here */
2630        if (sKillHandler == null) {
2631            sKillThread = new ServiceThread(TAG + ":kill",
2632                    android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2633            sKillThread.start();
2634            sKillHandler = new KillHandler(sKillThread.getLooper());
2635        }
2636
2637        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2638                "foreground", BROADCAST_FG_TIMEOUT, false);
2639        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2640                "background", BROADCAST_BG_TIMEOUT, true);
2641        mBroadcastQueues[0] = mFgBroadcastQueue;
2642        mBroadcastQueues[1] = mBgBroadcastQueue;
2643
2644        mServices = new ActiveServices(this);
2645        mProviderMap = new ProviderMap(this);
2646        mAppErrors = new AppErrors(mContext, this);
2647
2648        // TODO: Move creation of battery stats service outside of activity manager service.
2649        File dataDir = Environment.getDataDirectory();
2650        File systemDir = new File(dataDir, "system");
2651        systemDir.mkdirs();
2652        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2653        mBatteryStatsService.getActiveStatistics().readLocked();
2654        mBatteryStatsService.scheduleWriteToDisk();
2655        mOnBattery = DEBUG_POWER ? true
2656                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2657        mBatteryStatsService.getActiveStatistics().setCallback(this);
2658
2659        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2660
2661        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2662        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2663                new IAppOpsCallback.Stub() {
2664                    @Override public void opChanged(int op, int uid, String packageName) {
2665                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2666                            if (mAppOpsService.checkOperation(op, uid, packageName)
2667                                    != AppOpsManager.MODE_ALLOWED) {
2668                                runInBackgroundDisabled(uid);
2669                            }
2670                        }
2671                    }
2672                });
2673
2674        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2675
2676        mUserController = new UserController(this);
2677
2678        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2679            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2680
2681        if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
2682            mUseFifoUiScheduling = true;
2683        }
2684
2685        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2686
2687        mConfiguration.setToDefaults();
2688        mConfiguration.setLocales(LocaleList.getDefault());
2689
2690        mConfigurationSeq = mConfiguration.seq = 1;
2691        mProcessCpuTracker.init();
2692
2693        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2694        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2695        mStackSupervisor = new ActivityStackSupervisor(this);
2696        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2697        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2698
2699        mProcessCpuThread = new Thread("CpuTracker") {
2700            @Override
2701            public void run() {
2702                while (true) {
2703                    try {
2704                        try {
2705                            synchronized(this) {
2706                                final long now = SystemClock.uptimeMillis();
2707                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2708                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2709                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2710                                //        + ", write delay=" + nextWriteDelay);
2711                                if (nextWriteDelay < nextCpuDelay) {
2712                                    nextCpuDelay = nextWriteDelay;
2713                                }
2714                                if (nextCpuDelay > 0) {
2715                                    mProcessCpuMutexFree.set(true);
2716                                    this.wait(nextCpuDelay);
2717                                }
2718                            }
2719                        } catch (InterruptedException e) {
2720                        }
2721                        updateCpuStatsNow();
2722                    } catch (Exception e) {
2723                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2724                    }
2725                }
2726            }
2727        };
2728
2729        Watchdog.getInstance().addMonitor(this);
2730        Watchdog.getInstance().addThread(mHandler);
2731    }
2732
2733    public void setSystemServiceManager(SystemServiceManager mgr) {
2734        mSystemServiceManager = mgr;
2735    }
2736
2737    public void setInstaller(Installer installer) {
2738        mInstaller = installer;
2739    }
2740
2741    private void start() {
2742        Process.removeAllProcessGroups();
2743        mProcessCpuThread.start();
2744
2745        mBatteryStatsService.publish(mContext);
2746        mAppOpsService.publish(mContext);
2747        Slog.d("AppOps", "AppOpsService published");
2748        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2749    }
2750
2751    void onUserStoppedLocked(int userId) {
2752        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2753    }
2754
2755    public void initPowerManagement() {
2756        mStackSupervisor.initPowerManagement();
2757        mBatteryStatsService.initPowerManagement();
2758        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2759        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2760        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2761        mVoiceWakeLock.setReferenceCounted(false);
2762    }
2763
2764    @Override
2765    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2766            throws RemoteException {
2767        if (code == SYSPROPS_TRANSACTION) {
2768            // We need to tell all apps about the system property change.
2769            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2770            synchronized(this) {
2771                final int NP = mProcessNames.getMap().size();
2772                for (int ip=0; ip<NP; ip++) {
2773                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2774                    final int NA = apps.size();
2775                    for (int ia=0; ia<NA; ia++) {
2776                        ProcessRecord app = apps.valueAt(ia);
2777                        if (app.thread != null) {
2778                            procs.add(app.thread.asBinder());
2779                        }
2780                    }
2781                }
2782            }
2783
2784            int N = procs.size();
2785            for (int i=0; i<N; i++) {
2786                Parcel data2 = Parcel.obtain();
2787                try {
2788                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2789                } catch (RemoteException e) {
2790                }
2791                data2.recycle();
2792            }
2793        }
2794        try {
2795            return super.onTransact(code, data, reply, flags);
2796        } catch (RuntimeException e) {
2797            // The activity manager only throws security exceptions, so let's
2798            // log all others.
2799            if (!(e instanceof SecurityException)) {
2800                Slog.wtf(TAG, "Activity Manager Crash", e);
2801            }
2802            throw e;
2803        }
2804    }
2805
2806    void updateCpuStats() {
2807        final long now = SystemClock.uptimeMillis();
2808        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2809            return;
2810        }
2811        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2812            synchronized (mProcessCpuThread) {
2813                mProcessCpuThread.notify();
2814            }
2815        }
2816    }
2817
2818    void updateCpuStatsNow() {
2819        synchronized (mProcessCpuTracker) {
2820            mProcessCpuMutexFree.set(false);
2821            final long now = SystemClock.uptimeMillis();
2822            boolean haveNewCpuStats = false;
2823
2824            if (MONITOR_CPU_USAGE &&
2825                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2826                mLastCpuTime.set(now);
2827                mProcessCpuTracker.update();
2828                if (mProcessCpuTracker.hasGoodLastStats()) {
2829                    haveNewCpuStats = true;
2830                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2831                    //Slog.i(TAG, "Total CPU usage: "
2832                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2833
2834                    // Slog the cpu usage if the property is set.
2835                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2836                        int user = mProcessCpuTracker.getLastUserTime();
2837                        int system = mProcessCpuTracker.getLastSystemTime();
2838                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2839                        int irq = mProcessCpuTracker.getLastIrqTime();
2840                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2841                        int idle = mProcessCpuTracker.getLastIdleTime();
2842
2843                        int total = user + system + iowait + irq + softIrq + idle;
2844                        if (total == 0) total = 1;
2845
2846                        EventLog.writeEvent(EventLogTags.CPU,
2847                                ((user+system+iowait+irq+softIrq) * 100) / total,
2848                                (user * 100) / total,
2849                                (system * 100) / total,
2850                                (iowait * 100) / total,
2851                                (irq * 100) / total,
2852                                (softIrq * 100) / total);
2853                    }
2854                }
2855            }
2856
2857            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2858            synchronized(bstats) {
2859                synchronized(mPidsSelfLocked) {
2860                    if (haveNewCpuStats) {
2861                        if (bstats.startAddingCpuLocked()) {
2862                            int totalUTime = 0;
2863                            int totalSTime = 0;
2864                            final int N = mProcessCpuTracker.countStats();
2865                            for (int i=0; i<N; i++) {
2866                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2867                                if (!st.working) {
2868                                    continue;
2869                                }
2870                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2871                                totalUTime += st.rel_utime;
2872                                totalSTime += st.rel_stime;
2873                                if (pr != null) {
2874                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2875                                    if (ps == null || !ps.isActive()) {
2876                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2877                                                pr.info.uid, pr.processName);
2878                                    }
2879                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2880                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2881                                } else {
2882                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2883                                    if (ps == null || !ps.isActive()) {
2884                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2885                                                bstats.mapUid(st.uid), st.name);
2886                                    }
2887                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2888                                }
2889                            }
2890                            final int userTime = mProcessCpuTracker.getLastUserTime();
2891                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2892                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2893                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2894                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2895                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2896                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2897                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2898                        }
2899                    }
2900                }
2901
2902                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2903                    mLastWriteTime = now;
2904                    mBatteryStatsService.scheduleWriteToDisk();
2905                }
2906            }
2907        }
2908    }
2909
2910    @Override
2911    public void batteryNeedsCpuUpdate() {
2912        updateCpuStatsNow();
2913    }
2914
2915    @Override
2916    public void batteryPowerChanged(boolean onBattery) {
2917        // When plugging in, update the CPU stats first before changing
2918        // the plug state.
2919        updateCpuStatsNow();
2920        synchronized (this) {
2921            synchronized(mPidsSelfLocked) {
2922                mOnBattery = DEBUG_POWER ? true : onBattery;
2923            }
2924        }
2925    }
2926
2927    @Override
2928    public void batterySendBroadcast(Intent intent) {
2929        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2930                AppOpsManager.OP_NONE, null, false, false,
2931                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2932    }
2933
2934    /**
2935     * Initialize the application bind args. These are passed to each
2936     * process when the bindApplication() IPC is sent to the process. They're
2937     * lazily setup to make sure the services are running when they're asked for.
2938     */
2939    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2940        // Isolated processes won't get this optimization, so that we don't
2941        // violate the rules about which services they have access to.
2942        if (isolated) {
2943            if (mIsolatedAppBindArgs == null) {
2944                mIsolatedAppBindArgs = new HashMap<>();
2945                mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
2946            }
2947            return mIsolatedAppBindArgs;
2948        }
2949
2950        if (mAppBindArgs == null) {
2951            mAppBindArgs = new HashMap<>();
2952
2953            // Setup the application init args
2954            mAppBindArgs.put("package", ServiceManager.getService("package"));
2955            mAppBindArgs.put("window", ServiceManager.getService("window"));
2956            mAppBindArgs.put(Context.ALARM_SERVICE,
2957                    ServiceManager.getService(Context.ALARM_SERVICE));
2958        }
2959        return mAppBindArgs;
2960    }
2961
2962    boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2963        if (r == null || mFocusedActivity == r) {
2964            return false;
2965        }
2966
2967        if (!r.isFocusable()) {
2968            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2969            return false;
2970        }
2971
2972        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2973
2974        final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2975        if (wasDoingSetFocusedActivity) Slog.w(TAG,
2976                "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2977        mDoingSetFocusedActivity = true;
2978
2979        final ActivityRecord last = mFocusedActivity;
2980        mFocusedActivity = r;
2981        if (r.task.isApplicationTask()) {
2982            if (mCurAppTimeTracker != r.appTimeTracker) {
2983                // We are switching app tracking.  Complete the current one.
2984                if (mCurAppTimeTracker != null) {
2985                    mCurAppTimeTracker.stop();
2986                    mHandler.obtainMessage(
2987                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2988                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2989                    mCurAppTimeTracker = null;
2990                }
2991                if (r.appTimeTracker != null) {
2992                    mCurAppTimeTracker = r.appTimeTracker;
2993                    startTimeTrackingFocusedActivityLocked();
2994                }
2995            } else {
2996                startTimeTrackingFocusedActivityLocked();
2997            }
2998        } else {
2999            r.appTimeTracker = null;
3000        }
3001        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
3002        // TODO: Probably not, because we don't want to resume voice on switching
3003        // back to this activity
3004        if (r.task.voiceInteractor != null) {
3005            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
3006        } else {
3007            finishRunningVoiceLocked();
3008            IVoiceInteractionSession session;
3009            if (last != null && ((session = last.task.voiceSession) != null
3010                    || (session = last.voiceSession) != null)) {
3011                // We had been in a voice interaction session, but now focused has
3012                // move to something different.  Just finish the session, we can't
3013                // return to it and retain the proper state and synchronization with
3014                // the voice interaction service.
3015                finishVoiceTask(session);
3016            }
3017        }
3018        if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
3019            mWindowManager.setFocusedApp(r.appToken, true);
3020        }
3021        applyUpdateLockStateLocked(r);
3022        applyUpdateVrModeLocked(r);
3023        if (mFocusedActivity.userId != mLastFocusedUserId) {
3024            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3025            mHandler.obtainMessage(
3026                    FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
3027            mLastFocusedUserId = mFocusedActivity.userId;
3028        }
3029
3030        // Log a warning if the focused app is changed during the process. This could
3031        // indicate a problem of the focus setting logic!
3032        if (mFocusedActivity != r) Slog.w(TAG,
3033                "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
3034        mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
3035
3036        EventLogTags.writeAmFocusedActivity(
3037                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
3038                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
3039                reason);
3040        return true;
3041    }
3042
3043    final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
3044        if (mFocusedActivity != goingAway) {
3045            return;
3046        }
3047
3048        final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
3049        if (focusedStack != null) {
3050            final ActivityRecord top = focusedStack.topActivity();
3051            if (top != null && top.userId != mLastFocusedUserId) {
3052                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3053                mHandler.sendMessage(
3054                        mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
3055                mLastFocusedUserId = top.userId;
3056            }
3057        }
3058
3059        // Try to move focus to another activity if possible.
3060        if (setFocusedActivityLocked(
3061                focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
3062            return;
3063        }
3064
3065        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
3066                + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
3067        mFocusedActivity = null;
3068        EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
3069    }
3070
3071    @Override
3072    public void setFocusedStack(int stackId) {
3073        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3074        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3075        final long callingId = Binder.clearCallingIdentity();
3076        try {
3077            synchronized (this) {
3078                final ActivityStack stack = mStackSupervisor.getStack(stackId);
3079                if (stack == null) {
3080                    return;
3081                }
3082                final ActivityRecord r = stack.topRunningActivityLocked();
3083                if (setFocusedActivityLocked(r, "setFocusedStack")) {
3084                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3085                }
3086            }
3087        } finally {
3088            Binder.restoreCallingIdentity(callingId);
3089        }
3090    }
3091
3092    @Override
3093    public void setFocusedTask(int taskId) {
3094        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3095        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3096        final long callingId = Binder.clearCallingIdentity();
3097        try {
3098            synchronized (this) {
3099                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3100                if (task == null) {
3101                    return;
3102                }
3103                if (mUserController.shouldConfirmCredentials(task.userId)) {
3104                    mActivityStarter.showConfirmDeviceCredential(task.userId);
3105                    if (task.stack != null && task.stack.mStackId == FREEFORM_WORKSPACE_STACK_ID) {
3106                        mStackSupervisor.moveTaskToStackLocked(task.taskId,
3107                                FULLSCREEN_WORKSPACE_STACK_ID, !ON_TOP, !FORCE_FOCUS,
3108                                "setFocusedTask", ANIMATE);
3109                    }
3110                    return;
3111                }
3112                final ActivityRecord r = task.topRunningActivityLocked();
3113                if (setFocusedActivityLocked(r, "setFocusedTask")) {
3114                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3115                }
3116            }
3117        } finally {
3118            Binder.restoreCallingIdentity(callingId);
3119        }
3120    }
3121
3122    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3123    @Override
3124    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3125        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3126        synchronized (this) {
3127            if (listener != null) {
3128                mTaskStackListeners.register(listener);
3129            }
3130        }
3131    }
3132
3133    @Override
3134    public void notifyActivityDrawn(IBinder token) {
3135        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3136        synchronized (this) {
3137            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3138            if (r != null) {
3139                r.task.stack.notifyActivityDrawnLocked(r);
3140            }
3141        }
3142    }
3143
3144    final void applyUpdateLockStateLocked(ActivityRecord r) {
3145        // Modifications to the UpdateLock state are done on our handler, outside
3146        // the activity manager's locks.  The new state is determined based on the
3147        // state *now* of the relevant activity record.  The object is passed to
3148        // the handler solely for logging detail, not to be consulted/modified.
3149        final boolean nextState = r != null && r.immersive;
3150        mHandler.sendMessage(
3151                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3152    }
3153
3154    final void applyUpdateVrModeLocked(ActivityRecord r) {
3155        mHandler.sendMessage(
3156                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3157    }
3158
3159    private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
3160        mHandler.sendMessage(
3161                mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
3162    }
3163
3164    private void applyVrMode(boolean enabled, ComponentName packageName, int userId,
3165            ComponentName callingPackage, boolean immediate) {
3166        VrManagerInternal vrService =
3167                LocalServices.getService(VrManagerInternal.class);
3168        if (immediate) {
3169            vrService.setVrModeImmediate(enabled, packageName, userId, callingPackage);
3170        } else {
3171            vrService.setVrMode(enabled, packageName, userId, callingPackage);
3172        }
3173    }
3174
3175    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3176        Message msg = Message.obtain();
3177        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3178        msg.obj = r.task.askedCompatMode ? null : r;
3179        mUiHandler.sendMessage(msg);
3180    }
3181
3182    final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3183        if (mConfiguration.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3184                && r.appInfo.requiresSmallestWidthDp > mConfiguration.smallestScreenWidthDp) {
3185            final Message msg = Message.obtain();
3186            msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3187            msg.obj = r;
3188            mUiHandler.sendMessage(msg);
3189        }
3190    }
3191
3192    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3193            String what, Object obj, ProcessRecord srcApp) {
3194        app.lastActivityTime = now;
3195
3196        if (app.activities.size() > 0) {
3197            // Don't want to touch dependent processes that are hosting activities.
3198            return index;
3199        }
3200
3201        int lrui = mLruProcesses.lastIndexOf(app);
3202        if (lrui < 0) {
3203            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3204                    + what + " " + obj + " from " + srcApp);
3205            return index;
3206        }
3207
3208        if (lrui >= index) {
3209            // Don't want to cause this to move dependent processes *back* in the
3210            // list as if they were less frequently used.
3211            return index;
3212        }
3213
3214        if (lrui >= mLruProcessActivityStart) {
3215            // Don't want to touch dependent processes that are hosting activities.
3216            return index;
3217        }
3218
3219        mLruProcesses.remove(lrui);
3220        if (index > 0) {
3221            index--;
3222        }
3223        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3224                + " in LRU list: " + app);
3225        mLruProcesses.add(index, app);
3226        return index;
3227    }
3228
3229    static void killProcessGroup(int uid, int pid) {
3230        if (sKillHandler != null) {
3231            sKillHandler.sendMessage(
3232                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3233        } else {
3234            Slog.w(TAG, "Asked to kill process group before system bringup!");
3235            Process.killProcessGroup(uid, pid);
3236        }
3237    }
3238
3239    final void removeLruProcessLocked(ProcessRecord app) {
3240        int lrui = mLruProcesses.lastIndexOf(app);
3241        if (lrui >= 0) {
3242            if (!app.killed) {
3243                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3244                Process.killProcessQuiet(app.pid);
3245                killProcessGroup(app.uid, app.pid);
3246            }
3247            if (lrui <= mLruProcessActivityStart) {
3248                mLruProcessActivityStart--;
3249            }
3250            if (lrui <= mLruProcessServiceStart) {
3251                mLruProcessServiceStart--;
3252            }
3253            mLruProcesses.remove(lrui);
3254        }
3255    }
3256
3257    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3258            ProcessRecord client) {
3259        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3260                || app.treatLikeActivity;
3261        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3262        if (!activityChange && hasActivity) {
3263            // The process has activities, so we are only allowing activity-based adjustments
3264            // to move it.  It should be kept in the front of the list with other
3265            // processes that have activities, and we don't want those to change their
3266            // order except due to activity operations.
3267            return;
3268        }
3269
3270        mLruSeq++;
3271        final long now = SystemClock.uptimeMillis();
3272        app.lastActivityTime = now;
3273
3274        // First a quick reject: if the app is already at the position we will
3275        // put it, then there is nothing to do.
3276        if (hasActivity) {
3277            final int N = mLruProcesses.size();
3278            if (N > 0 && mLruProcesses.get(N-1) == app) {
3279                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3280                return;
3281            }
3282        } else {
3283            if (mLruProcessServiceStart > 0
3284                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3285                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3286                return;
3287            }
3288        }
3289
3290        int lrui = mLruProcesses.lastIndexOf(app);
3291
3292        if (app.persistent && lrui >= 0) {
3293            // We don't care about the position of persistent processes, as long as
3294            // they are in the list.
3295            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3296            return;
3297        }
3298
3299        /* In progress: compute new position first, so we can avoid doing work
3300           if the process is not actually going to move.  Not yet working.
3301        int addIndex;
3302        int nextIndex;
3303        boolean inActivity = false, inService = false;
3304        if (hasActivity) {
3305            // Process has activities, put it at the very tipsy-top.
3306            addIndex = mLruProcesses.size();
3307            nextIndex = mLruProcessServiceStart;
3308            inActivity = true;
3309        } else if (hasService) {
3310            // Process has services, put it at the top of the service list.
3311            addIndex = mLruProcessActivityStart;
3312            nextIndex = mLruProcessServiceStart;
3313            inActivity = true;
3314            inService = true;
3315        } else  {
3316            // Process not otherwise of interest, it goes to the top of the non-service area.
3317            addIndex = mLruProcessServiceStart;
3318            if (client != null) {
3319                int clientIndex = mLruProcesses.lastIndexOf(client);
3320                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3321                        + app);
3322                if (clientIndex >= 0 && addIndex > clientIndex) {
3323                    addIndex = clientIndex;
3324                }
3325            }
3326            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3327        }
3328
3329        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3330                + mLruProcessActivityStart + "): " + app);
3331        */
3332
3333        if (lrui >= 0) {
3334            if (lrui < mLruProcessActivityStart) {
3335                mLruProcessActivityStart--;
3336            }
3337            if (lrui < mLruProcessServiceStart) {
3338                mLruProcessServiceStart--;
3339            }
3340            /*
3341            if (addIndex > lrui) {
3342                addIndex--;
3343            }
3344            if (nextIndex > lrui) {
3345                nextIndex--;
3346            }
3347            */
3348            mLruProcesses.remove(lrui);
3349        }
3350
3351        /*
3352        mLruProcesses.add(addIndex, app);
3353        if (inActivity) {
3354            mLruProcessActivityStart++;
3355        }
3356        if (inService) {
3357            mLruProcessActivityStart++;
3358        }
3359        */
3360
3361        int nextIndex;
3362        if (hasActivity) {
3363            final int N = mLruProcesses.size();
3364            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3365                // Process doesn't have activities, but has clients with
3366                // activities...  move it up, but one below the top (the top
3367                // should always have a real activity).
3368                if (DEBUG_LRU) Slog.d(TAG_LRU,
3369                        "Adding to second-top of LRU activity list: " + app);
3370                mLruProcesses.add(N - 1, app);
3371                // To keep it from spamming the LRU list (by making a bunch of clients),
3372                // we will push down any other entries owned by the app.
3373                final int uid = app.info.uid;
3374                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3375                    ProcessRecord subProc = mLruProcesses.get(i);
3376                    if (subProc.info.uid == uid) {
3377                        // We want to push this one down the list.  If the process after
3378                        // it is for the same uid, however, don't do so, because we don't
3379                        // want them internally to be re-ordered.
3380                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3381                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3382                                    "Pushing uid " + uid + " swapping at " + i + ": "
3383                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3384                            ProcessRecord tmp = mLruProcesses.get(i);
3385                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3386                            mLruProcesses.set(i - 1, tmp);
3387                            i--;
3388                        }
3389                    } else {
3390                        // A gap, we can stop here.
3391                        break;
3392                    }
3393                }
3394            } else {
3395                // Process has activities, put it at the very tipsy-top.
3396                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3397                mLruProcesses.add(app);
3398            }
3399            nextIndex = mLruProcessServiceStart;
3400        } else if (hasService) {
3401            // Process has services, put it at the top of the service list.
3402            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3403            mLruProcesses.add(mLruProcessActivityStart, app);
3404            nextIndex = mLruProcessServiceStart;
3405            mLruProcessActivityStart++;
3406        } else  {
3407            // Process not otherwise of interest, it goes to the top of the non-service area.
3408            int index = mLruProcessServiceStart;
3409            if (client != null) {
3410                // If there is a client, don't allow the process to be moved up higher
3411                // in the list than that client.
3412                int clientIndex = mLruProcesses.lastIndexOf(client);
3413                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3414                        + " when updating " + app);
3415                if (clientIndex <= lrui) {
3416                    // Don't allow the client index restriction to push it down farther in the
3417                    // list than it already is.
3418                    clientIndex = lrui;
3419                }
3420                if (clientIndex >= 0 && index > clientIndex) {
3421                    index = clientIndex;
3422                }
3423            }
3424            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3425            mLruProcesses.add(index, app);
3426            nextIndex = index-1;
3427            mLruProcessActivityStart++;
3428            mLruProcessServiceStart++;
3429        }
3430
3431        // If the app is currently using a content provider or service,
3432        // bump those processes as well.
3433        for (int j=app.connections.size()-1; j>=0; j--) {
3434            ConnectionRecord cr = app.connections.valueAt(j);
3435            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3436                    && cr.binding.service.app != null
3437                    && cr.binding.service.app.lruSeq != mLruSeq
3438                    && !cr.binding.service.app.persistent) {
3439                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3440                        "service connection", cr, app);
3441            }
3442        }
3443        for (int j=app.conProviders.size()-1; j>=0; j--) {
3444            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3445            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3446                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3447                        "provider reference", cpr, app);
3448            }
3449        }
3450    }
3451
3452    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3453        if (uid == Process.SYSTEM_UID) {
3454            // The system gets to run in any process.  If there are multiple
3455            // processes with the same uid, just pick the first (this
3456            // should never happen).
3457            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3458            if (procs == null) return null;
3459            final int procCount = procs.size();
3460            for (int i = 0; i < procCount; i++) {
3461                final int procUid = procs.keyAt(i);
3462                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3463                    // Don't use an app process or different user process for system component.
3464                    continue;
3465                }
3466                return procs.valueAt(i);
3467            }
3468        }
3469        ProcessRecord proc = mProcessNames.get(processName, uid);
3470        if (false && proc != null && !keepIfLarge
3471                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3472                && proc.lastCachedPss >= 4000) {
3473            // Turn this condition on to cause killing to happen regularly, for testing.
3474            if (proc.baseProcessTracker != null) {
3475                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3476            }
3477            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3478        } else if (proc != null && !keepIfLarge
3479                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3480                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3481            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3482            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3483                if (proc.baseProcessTracker != null) {
3484                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3485                }
3486                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3487            }
3488        }
3489        return proc;
3490    }
3491
3492    void notifyPackageUse(String packageName, int reason) {
3493        IPackageManager pm = AppGlobals.getPackageManager();
3494        try {
3495            pm.notifyPackageUse(packageName, reason);
3496        } catch (RemoteException e) {
3497        }
3498    }
3499
3500    boolean isNextTransitionForward() {
3501        int transit = mWindowManager.getPendingAppTransition();
3502        return transit == TRANSIT_ACTIVITY_OPEN
3503                || transit == TRANSIT_TASK_OPEN
3504                || transit == TRANSIT_TASK_TO_FRONT;
3505    }
3506
3507    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3508            String processName, String abiOverride, int uid, Runnable crashHandler) {
3509        synchronized(this) {
3510            ApplicationInfo info = new ApplicationInfo();
3511            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3512            // For isolated processes, the former contains the parent's uid and the latter the
3513            // actual uid of the isolated process.
3514            // In the special case introduced by this method (which is, starting an isolated
3515            // process directly from the SystemServer without an actual parent app process) the
3516            // closest thing to a parent's uid is SYSTEM_UID.
3517            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3518            // the |isolated| logic in the ProcessRecord constructor.
3519            info.uid = Process.SYSTEM_UID;
3520            info.processName = processName;
3521            info.className = entryPoint;
3522            info.packageName = "android";
3523            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3524                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3525                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3526                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3527                    crashHandler);
3528            return proc != null ? proc.pid : 0;
3529        }
3530    }
3531
3532    final ProcessRecord startProcessLocked(String processName,
3533            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3534            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3535            boolean isolated, boolean keepIfLarge) {
3536        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3537                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3538                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3539                null /* crashHandler */);
3540    }
3541
3542    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3543            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3544            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3545            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3546        long startTime = SystemClock.elapsedRealtime();
3547        ProcessRecord app;
3548        if (!isolated) {
3549            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3550            checkTime(startTime, "startProcess: after getProcessRecord");
3551
3552            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3553                // If we are in the background, then check to see if this process
3554                // is bad.  If so, we will just silently fail.
3555                if (mAppErrors.isBadProcessLocked(info)) {
3556                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3557                            + "/" + info.processName);
3558                    return null;
3559                }
3560            } else {
3561                // When the user is explicitly starting a process, then clear its
3562                // crash count so that we won't make it bad until they see at
3563                // least one crash dialog again, and make the process good again
3564                // if it had been bad.
3565                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3566                        + "/" + info.processName);
3567                mAppErrors.resetProcessCrashTimeLocked(info);
3568                if (mAppErrors.isBadProcessLocked(info)) {
3569                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3570                            UserHandle.getUserId(info.uid), info.uid,
3571                            info.processName);
3572                    mAppErrors.clearBadProcessLocked(info);
3573                    if (app != null) {
3574                        app.bad = false;
3575                    }
3576                }
3577            }
3578        } else {
3579            // If this is an isolated process, it can't re-use an existing process.
3580            app = null;
3581        }
3582
3583        // app launch boost for big.little configurations
3584        // use cpusets to migrate freshly launched tasks to big cores
3585        nativeMigrateToBoost();
3586        mIsBoosted = true;
3587        mBoostStartTime = SystemClock.uptimeMillis();
3588        Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3589        mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3590
3591        // We don't have to do anything more if:
3592        // (1) There is an existing application record; and
3593        // (2) The caller doesn't think it is dead, OR there is no thread
3594        //     object attached to it so we know it couldn't have crashed; and
3595        // (3) There is a pid assigned to it, so it is either starting or
3596        //     already running.
3597        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3598                + " app=" + app + " knownToBeDead=" + knownToBeDead
3599                + " thread=" + (app != null ? app.thread : null)
3600                + " pid=" + (app != null ? app.pid : -1));
3601        if (app != null && app.pid > 0) {
3602            if ((!knownToBeDead && !app.killed) || app.thread == null) {
3603                // We already have the app running, or are waiting for it to
3604                // come up (we have a pid but not yet its thread), so keep it.
3605                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3606                // If this is a new package in the process, add the package to the list
3607                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3608                checkTime(startTime, "startProcess: done, added package to proc");
3609                return app;
3610            }
3611
3612            // An application record is attached to a previous process,
3613            // clean it up now.
3614            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3615            checkTime(startTime, "startProcess: bad proc running, killing");
3616            killProcessGroup(app.uid, app.pid);
3617            handleAppDiedLocked(app, true, true);
3618            checkTime(startTime, "startProcess: done killing old proc");
3619        }
3620
3621        String hostingNameStr = hostingName != null
3622                ? hostingName.flattenToShortString() : null;
3623
3624        if (app == null) {
3625            checkTime(startTime, "startProcess: creating new process record");
3626            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3627            if (app == null) {
3628                Slog.w(TAG, "Failed making new process record for "
3629                        + processName + "/" + info.uid + " isolated=" + isolated);
3630                return null;
3631            }
3632            app.crashHandler = crashHandler;
3633            checkTime(startTime, "startProcess: done creating new process record");
3634        } else {
3635            // If this is a new package in the process, add the package to the list
3636            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3637            checkTime(startTime, "startProcess: added package to existing proc");
3638        }
3639
3640        // If the system is not ready yet, then hold off on starting this
3641        // process until it is.
3642        if (!mProcessesReady
3643                && !isAllowedWhileBooting(info)
3644                && !allowWhileBooting) {
3645            if (!mProcessesOnHold.contains(app)) {
3646                mProcessesOnHold.add(app);
3647            }
3648            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3649                    "System not ready, putting on hold: " + app);
3650            checkTime(startTime, "startProcess: returning with proc on hold");
3651            return app;
3652        }
3653
3654        checkTime(startTime, "startProcess: stepping in to startProcess");
3655        startProcessLocked(
3656                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3657        checkTime(startTime, "startProcess: done starting proc!");
3658        return (app.pid != 0) ? app : null;
3659    }
3660
3661    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3662        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3663    }
3664
3665    private final void startProcessLocked(ProcessRecord app,
3666            String hostingType, String hostingNameStr) {
3667        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3668                null /* entryPoint */, null /* entryPointArgs */);
3669    }
3670
3671    private final void startProcessLocked(ProcessRecord app, String hostingType,
3672            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3673        long startTime = SystemClock.elapsedRealtime();
3674        if (app.pid > 0 && app.pid != MY_PID) {
3675            checkTime(startTime, "startProcess: removing from pids map");
3676            synchronized (mPidsSelfLocked) {
3677                mPidsSelfLocked.remove(app.pid);
3678                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3679            }
3680            checkTime(startTime, "startProcess: done removing from pids map");
3681            app.setPid(0);
3682        }
3683
3684        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3685                "startProcessLocked removing on hold: " + app);
3686        mProcessesOnHold.remove(app);
3687
3688        checkTime(startTime, "startProcess: starting to update cpu stats");
3689        updateCpuStats();
3690        checkTime(startTime, "startProcess: done updating cpu stats");
3691
3692        try {
3693            try {
3694                final int userId = UserHandle.getUserId(app.uid);
3695                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3696            } catch (RemoteException e) {
3697                throw e.rethrowAsRuntimeException();
3698            }
3699
3700            int uid = app.uid;
3701            int[] gids = null;
3702            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3703            if (!app.isolated) {
3704                int[] permGids = null;
3705                try {
3706                    checkTime(startTime, "startProcess: getting gids from package manager");
3707                    final IPackageManager pm = AppGlobals.getPackageManager();
3708                    permGids = pm.getPackageGids(app.info.packageName,
3709                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3710                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3711                            MountServiceInternal.class);
3712                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3713                            app.info.packageName);
3714                } catch (RemoteException e) {
3715                    throw e.rethrowAsRuntimeException();
3716                }
3717
3718                /*
3719                 * Add shared application and profile GIDs so applications can share some
3720                 * resources like shared libraries and access user-wide resources
3721                 */
3722                if (ArrayUtils.isEmpty(permGids)) {
3723                    gids = new int[2];
3724                } else {
3725                    gids = new int[permGids.length + 2];
3726                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3727                }
3728                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3729                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3730            }
3731            checkTime(startTime, "startProcess: building args");
3732            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3733                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3734                        && mTopComponent != null
3735                        && app.processName.equals(mTopComponent.getPackageName())) {
3736                    uid = 0;
3737                }
3738                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3739                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3740                    uid = 0;
3741                }
3742            }
3743            int debugFlags = 0;
3744            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3745                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3746                // Also turn on CheckJNI for debuggable apps. It's quite
3747                // awkward to turn on otherwise.
3748                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3749            }
3750            // Run the app in safe mode if its manifest requests so or the
3751            // system is booted in safe mode.
3752            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3753                mSafeMode == true) {
3754                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3755            }
3756            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3757                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3758            }
3759            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3760            if ("true".equals(genDebugInfoProperty)) {
3761                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3762            }
3763            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3764                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3765            }
3766            if ("1".equals(SystemProperties.get("debug.assert"))) {
3767                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3768            }
3769            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3770                // Enable all debug flags required by the native debugger.
3771                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3772                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3773                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3774                mNativeDebuggingApp = null;
3775            }
3776
3777            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3778            if (requiredAbi == null) {
3779                requiredAbi = Build.SUPPORTED_ABIS[0];
3780            }
3781
3782            String instructionSet = null;
3783            if (app.info.primaryCpuAbi != null) {
3784                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3785            }
3786
3787            app.gids = gids;
3788            app.requiredAbi = requiredAbi;
3789            app.instructionSet = instructionSet;
3790
3791            // Start the process.  It will either succeed and return a result containing
3792            // the PID of the new process, or else throw a RuntimeException.
3793            boolean isActivityProcess = (entryPoint == null);
3794            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3795            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3796                    app.processName);
3797            checkTime(startTime, "startProcess: asking zygote to start proc");
3798            Process.ProcessStartResult startResult = Process.start(entryPoint,
3799                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3800                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3801                    app.info.dataDir, entryPointArgs);
3802            checkTime(startTime, "startProcess: returned from zygote!");
3803            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3804
3805            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3806            checkTime(startTime, "startProcess: done updating battery stats");
3807
3808            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3809                    UserHandle.getUserId(uid), startResult.pid, uid,
3810                    app.processName, hostingType,
3811                    hostingNameStr != null ? hostingNameStr : "");
3812
3813            try {
3814                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3815                        app.info.seinfo, app.info.sourceDir, startResult.pid);
3816            } catch (RemoteException ex) {
3817                // Ignore
3818            }
3819
3820            if (app.persistent) {
3821                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3822            }
3823
3824            checkTime(startTime, "startProcess: building log message");
3825            StringBuilder buf = mStringBuilder;
3826            buf.setLength(0);
3827            buf.append("Start proc ");
3828            buf.append(startResult.pid);
3829            buf.append(':');
3830            buf.append(app.processName);
3831            buf.append('/');
3832            UserHandle.formatUid(buf, uid);
3833            if (!isActivityProcess) {
3834                buf.append(" [");
3835                buf.append(entryPoint);
3836                buf.append("]");
3837            }
3838            buf.append(" for ");
3839            buf.append(hostingType);
3840            if (hostingNameStr != null) {
3841                buf.append(" ");
3842                buf.append(hostingNameStr);
3843            }
3844            Slog.i(TAG, buf.toString());
3845            app.setPid(startResult.pid);
3846            app.usingWrapper = startResult.usingWrapper;
3847            app.removed = false;
3848            app.killed = false;
3849            app.killedByAm = false;
3850            checkTime(startTime, "startProcess: starting to update pids map");
3851            ProcessRecord oldApp;
3852            synchronized (mPidsSelfLocked) {
3853                oldApp = mPidsSelfLocked.get(startResult.pid);
3854            }
3855            // If there is already an app occupying that pid that hasn't been cleaned up
3856            if (oldApp != null && !app.isolated) {
3857                // Clean up anything relating to this pid first
3858                Slog.w(TAG, "Reusing pid " + startResult.pid
3859                        + " while app is still mapped to it");
3860                cleanUpApplicationRecordLocked(oldApp, false, false, -1,
3861                        true /*replacingPid*/);
3862            }
3863            synchronized (mPidsSelfLocked) {
3864                this.mPidsSelfLocked.put(startResult.pid, app);
3865                if (isActivityProcess) {
3866                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3867                    msg.obj = app;
3868                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3869                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3870                }
3871            }
3872            checkTime(startTime, "startProcess: done updating pids map");
3873        } catch (RuntimeException e) {
3874            Slog.e(TAG, "Failure starting process " + app.processName, e);
3875
3876            // Something went very wrong while trying to start this process; one
3877            // common case is when the package is frozen due to an active
3878            // upgrade. To recover, clean up any active bookkeeping related to
3879            // starting this process. (We already invoked this method once when
3880            // the package was initially frozen through KILL_APPLICATION_MSG, so
3881            // it doesn't hurt to use it again.)
3882            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3883                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3884        }
3885    }
3886
3887    void updateUsageStats(ActivityRecord component, boolean resumed) {
3888        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3889                "updateUsageStats: comp=" + component + "res=" + resumed);
3890        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3891        if (resumed) {
3892            if (mUsageStatsService != null) {
3893                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3894                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3895            }
3896            synchronized (stats) {
3897                stats.noteActivityResumedLocked(component.app.uid);
3898            }
3899        } else {
3900            if (mUsageStatsService != null) {
3901                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3902                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3903            }
3904            synchronized (stats) {
3905                stats.noteActivityPausedLocked(component.app.uid);
3906            }
3907        }
3908    }
3909
3910    Intent getHomeIntent() {
3911        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3912        intent.setComponent(mTopComponent);
3913        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3914        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3915            intent.addCategory(Intent.CATEGORY_HOME);
3916        }
3917        return intent;
3918    }
3919
3920    boolean startHomeActivityLocked(int userId, String reason) {
3921        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3922                && mTopAction == null) {
3923            // We are running in factory test mode, but unable to find
3924            // the factory test app, so just sit around displaying the
3925            // error message and don't try to start anything.
3926            return false;
3927        }
3928        Intent intent = getHomeIntent();
3929        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3930        if (aInfo != null) {
3931            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3932            // Don't do this if the home app is currently being
3933            // instrumented.
3934            aInfo = new ActivityInfo(aInfo);
3935            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3936            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3937                    aInfo.applicationInfo.uid, true);
3938            if (app == null || app.instrumentationClass == null) {
3939                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3940                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3941            }
3942        } else {
3943            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3944        }
3945
3946        return true;
3947    }
3948
3949    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3950        ActivityInfo ai = null;
3951        ComponentName comp = intent.getComponent();
3952        try {
3953            if (comp != null) {
3954                // Factory test.
3955                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3956            } else {
3957                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3958                        intent,
3959                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3960                        flags, userId);
3961
3962                if (info != null) {
3963                    ai = info.activityInfo;
3964                }
3965            }
3966        } catch (RemoteException e) {
3967            // ignore
3968        }
3969
3970        return ai;
3971    }
3972
3973    /**
3974     * Starts the "new version setup screen" if appropriate.
3975     */
3976    void startSetupActivityLocked() {
3977        // Only do this once per boot.
3978        if (mCheckedForSetup) {
3979            return;
3980        }
3981
3982        // We will show this screen if the current one is a different
3983        // version than the last one shown, and we are not running in
3984        // low-level factory test mode.
3985        final ContentResolver resolver = mContext.getContentResolver();
3986        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3987                Settings.Global.getInt(resolver,
3988                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3989            mCheckedForSetup = true;
3990
3991            // See if we should be showing the platform update setup UI.
3992            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3993            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3994                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3995            if (!ris.isEmpty()) {
3996                final ResolveInfo ri = ris.get(0);
3997                String vers = ri.activityInfo.metaData != null
3998                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3999                        : null;
4000                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
4001                    vers = ri.activityInfo.applicationInfo.metaData.getString(
4002                            Intent.METADATA_SETUP_VERSION);
4003                }
4004                String lastVers = Settings.Secure.getString(
4005                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
4006                if (vers != null && !vers.equals(lastVers)) {
4007                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
4008                    intent.setComponent(new ComponentName(
4009                            ri.activityInfo.packageName, ri.activityInfo.name));
4010                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
4011                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
4012                            null, 0, 0, 0, null, false, false, null, null, null);
4013                }
4014            }
4015        }
4016    }
4017
4018    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
4019        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
4020    }
4021
4022    void enforceNotIsolatedCaller(String caller) {
4023        if (UserHandle.isIsolated(Binder.getCallingUid())) {
4024            throw new SecurityException("Isolated process not allowed to call " + caller);
4025        }
4026    }
4027
4028    void enforceShellRestriction(String restriction, int userHandle) {
4029        if (Binder.getCallingUid() == Process.SHELL_UID) {
4030            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
4031                throw new SecurityException("Shell does not have permission to access user "
4032                        + userHandle);
4033            }
4034        }
4035    }
4036
4037    @Override
4038    public int getFrontActivityScreenCompatMode() {
4039        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4040        synchronized (this) {
4041            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4042        }
4043    }
4044
4045    @Override
4046    public void setFrontActivityScreenCompatMode(int mode) {
4047        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4048                "setFrontActivityScreenCompatMode");
4049        synchronized (this) {
4050            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4051        }
4052    }
4053
4054    @Override
4055    public int getPackageScreenCompatMode(String packageName) {
4056        enforceNotIsolatedCaller("getPackageScreenCompatMode");
4057        synchronized (this) {
4058            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4059        }
4060    }
4061
4062    @Override
4063    public void setPackageScreenCompatMode(String packageName, int mode) {
4064        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4065                "setPackageScreenCompatMode");
4066        synchronized (this) {
4067            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4068        }
4069    }
4070
4071    @Override
4072    public boolean getPackageAskScreenCompat(String packageName) {
4073        enforceNotIsolatedCaller("getPackageAskScreenCompat");
4074        synchronized (this) {
4075            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4076        }
4077    }
4078
4079    @Override
4080    public void setPackageAskScreenCompat(String packageName, boolean ask) {
4081        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4082                "setPackageAskScreenCompat");
4083        synchronized (this) {
4084            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4085        }
4086    }
4087
4088    private boolean hasUsageStatsPermission(String callingPackage) {
4089        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4090                Binder.getCallingUid(), callingPackage);
4091        if (mode == AppOpsManager.MODE_DEFAULT) {
4092            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4093                    == PackageManager.PERMISSION_GRANTED;
4094        }
4095        return mode == AppOpsManager.MODE_ALLOWED;
4096    }
4097
4098    @Override
4099    public int getPackageProcessState(String packageName, String callingPackage) {
4100        if (!hasUsageStatsPermission(callingPackage)) {
4101            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
4102                    "getPackageProcessState");
4103        }
4104
4105        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4106        synchronized (this) {
4107            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4108                final ProcessRecord proc = mLruProcesses.get(i);
4109                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
4110                        || procState > proc.setProcState) {
4111                    boolean found = false;
4112                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
4113                        if (proc.pkgList.keyAt(j).equals(packageName)) {
4114                            procState = proc.setProcState;
4115                            found = true;
4116                        }
4117                    }
4118                    if (proc.pkgDeps != null && !found) {
4119                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
4120                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
4121                                procState = proc.setProcState;
4122                                break;
4123                            }
4124                        }
4125                    }
4126                }
4127            }
4128        }
4129        return procState;
4130    }
4131
4132    @Override
4133    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
4134        synchronized (this) {
4135            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4136            if (app == null) {
4137                return false;
4138            }
4139            if (app.trimMemoryLevel < level && app.thread != null &&
4140                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4141                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4142                try {
4143                    app.thread.scheduleTrimMemory(level);
4144                    app.trimMemoryLevel = level;
4145                    return true;
4146                } catch (RemoteException e) {
4147                    // Fallthrough to failure case.
4148                }
4149            }
4150        }
4151        return false;
4152    }
4153
4154    private void dispatchProcessesChanged() {
4155        int N;
4156        synchronized (this) {
4157            N = mPendingProcessChanges.size();
4158            if (mActiveProcessChanges.length < N) {
4159                mActiveProcessChanges = new ProcessChangeItem[N];
4160            }
4161            mPendingProcessChanges.toArray(mActiveProcessChanges);
4162            mPendingProcessChanges.clear();
4163            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4164                    "*** Delivering " + N + " process changes");
4165        }
4166
4167        int i = mProcessObservers.beginBroadcast();
4168        while (i > 0) {
4169            i--;
4170            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4171            if (observer != null) {
4172                try {
4173                    for (int j=0; j<N; j++) {
4174                        ProcessChangeItem item = mActiveProcessChanges[j];
4175                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4176                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4177                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4178                                    + item.uid + ": " + item.foregroundActivities);
4179                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4180                                    item.foregroundActivities);
4181                        }
4182                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4183                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4184                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4185                                    + ": " + item.processState);
4186                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4187                        }
4188                    }
4189                } catch (RemoteException e) {
4190                }
4191            }
4192        }
4193        mProcessObservers.finishBroadcast();
4194
4195        synchronized (this) {
4196            for (int j=0; j<N; j++) {
4197                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4198            }
4199        }
4200    }
4201
4202    private void dispatchProcessDied(int pid, int uid) {
4203        int i = mProcessObservers.beginBroadcast();
4204        while (i > 0) {
4205            i--;
4206            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4207            if (observer != null) {
4208                try {
4209                    observer.onProcessDied(pid, uid);
4210                } catch (RemoteException e) {
4211                }
4212            }
4213        }
4214        mProcessObservers.finishBroadcast();
4215    }
4216
4217    private void dispatchUidsChanged() {
4218        int N;
4219        synchronized (this) {
4220            N = mPendingUidChanges.size();
4221            if (mActiveUidChanges.length < N) {
4222                mActiveUidChanges = new UidRecord.ChangeItem[N];
4223            }
4224            for (int i=0; i<N; i++) {
4225                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4226                mActiveUidChanges[i] = change;
4227                if (change.uidRecord != null) {
4228                    change.uidRecord.pendingChange = null;
4229                    change.uidRecord = null;
4230                }
4231            }
4232            mPendingUidChanges.clear();
4233            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4234                    "*** Delivering " + N + " uid changes");
4235        }
4236
4237        if (mLocalPowerManager != null) {
4238            for (int j=0; j<N; j++) {
4239                UidRecord.ChangeItem item = mActiveUidChanges[j];
4240                if (item.change == UidRecord.CHANGE_GONE
4241                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
4242                    mLocalPowerManager.uidGone(item.uid);
4243                } else {
4244                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4245                }
4246            }
4247        }
4248
4249        int i = mUidObservers.beginBroadcast();
4250        while (i > 0) {
4251            i--;
4252            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4253            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4254            if (observer != null) {
4255                try {
4256                    for (int j=0; j<N; j++) {
4257                        UidRecord.ChangeItem item = mActiveUidChanges[j];
4258                        final int change = item.change;
4259                        UidRecord validateUid = null;
4260                        if (VALIDATE_UID_STATES && i == 0) {
4261                            validateUid = mValidateUids.get(item.uid);
4262                            if (validateUid == null && change != UidRecord.CHANGE_GONE
4263                                    && change != UidRecord.CHANGE_GONE_IDLE) {
4264                                validateUid = new UidRecord(item.uid);
4265                                mValidateUids.put(item.uid, validateUid);
4266                            }
4267                        }
4268                        if (change == UidRecord.CHANGE_IDLE
4269                                || change == UidRecord.CHANGE_GONE_IDLE) {
4270                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4271                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4272                                        "UID idle uid=" + item.uid);
4273                                observer.onUidIdle(item.uid);
4274                            }
4275                            if (VALIDATE_UID_STATES && i == 0) {
4276                                if (validateUid != null) {
4277                                    validateUid.idle = true;
4278                                }
4279                            }
4280                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4281                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4282                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4283                                        "UID active uid=" + item.uid);
4284                                observer.onUidActive(item.uid);
4285                            }
4286                            if (VALIDATE_UID_STATES && i == 0) {
4287                                validateUid.idle = false;
4288                            }
4289                        }
4290                        if (change == UidRecord.CHANGE_GONE
4291                                || change == UidRecord.CHANGE_GONE_IDLE) {
4292                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4293                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4294                                        "UID gone uid=" + item.uid);
4295                                observer.onUidGone(item.uid);
4296                            }
4297                            if (VALIDATE_UID_STATES && i == 0) {
4298                                if (validateUid != null) {
4299                                    mValidateUids.remove(item.uid);
4300                                }
4301                            }
4302                        } else {
4303                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4304                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4305                                        "UID CHANGED uid=" + item.uid
4306                                                + ": " + item.processState);
4307                                observer.onUidStateChanged(item.uid, item.processState);
4308                            }
4309                            if (VALIDATE_UID_STATES && i == 0) {
4310                                validateUid.curProcState = validateUid.setProcState
4311                                        = item.processState;
4312                            }
4313                        }
4314                    }
4315                } catch (RemoteException e) {
4316                }
4317            }
4318        }
4319        mUidObservers.finishBroadcast();
4320
4321        synchronized (this) {
4322            for (int j=0; j<N; j++) {
4323                mAvailUidChanges.add(mActiveUidChanges[j]);
4324            }
4325        }
4326    }
4327
4328    @Override
4329    public final int startActivity(IApplicationThread caller, String callingPackage,
4330            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4331            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4332        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4333                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4334                UserHandle.getCallingUserId());
4335    }
4336
4337    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4338        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4339        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4340                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4341                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4342
4343        // TODO: Switch to user app stacks here.
4344        String mimeType = intent.getType();
4345        final Uri data = intent.getData();
4346        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4347            mimeType = getProviderMimeType(data, userId);
4348        }
4349        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4350
4351        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4352        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4353                null, 0, 0, null, null, null, null, false, userId, container, null);
4354    }
4355
4356    @Override
4357    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4358            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4359            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4360        enforceNotIsolatedCaller("startActivity");
4361        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4362                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4363        // TODO: Switch to user app stacks here.
4364        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4365                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4366                profilerInfo, null, null, bOptions, false, userId, null, null);
4367    }
4368
4369    @Override
4370    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4371            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4372            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4373            int userId) {
4374
4375        // This is very dangerous -- it allows you to perform a start activity (including
4376        // permission grants) as any app that may launch one of your own activities.  So
4377        // we will only allow this to be done from activities that are part of the core framework,
4378        // and then only when they are running as the system.
4379        final ActivityRecord sourceRecord;
4380        final int targetUid;
4381        final String targetPackage;
4382        synchronized (this) {
4383            if (resultTo == null) {
4384                throw new SecurityException("Must be called from an activity");
4385            }
4386            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4387            if (sourceRecord == null) {
4388                throw new SecurityException("Called with bad activity token: " + resultTo);
4389            }
4390            if (!sourceRecord.info.packageName.equals("android")) {
4391                throw new SecurityException(
4392                        "Must be called from an activity that is declared in the android package");
4393            }
4394            if (sourceRecord.app == null) {
4395                throw new SecurityException("Called without a process attached to activity");
4396            }
4397            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4398                // This is still okay, as long as this activity is running under the
4399                // uid of the original calling activity.
4400                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4401                    throw new SecurityException(
4402                            "Calling activity in uid " + sourceRecord.app.uid
4403                                    + " must be system uid or original calling uid "
4404                                    + sourceRecord.launchedFromUid);
4405                }
4406            }
4407            if (ignoreTargetSecurity) {
4408                if (intent.getComponent() == null) {
4409                    throw new SecurityException(
4410                            "Component must be specified with ignoreTargetSecurity");
4411                }
4412                if (intent.getSelector() != null) {
4413                    throw new SecurityException(
4414                            "Selector not allowed with ignoreTargetSecurity");
4415                }
4416            }
4417            targetUid = sourceRecord.launchedFromUid;
4418            targetPackage = sourceRecord.launchedFromPackage;
4419        }
4420
4421        if (userId == UserHandle.USER_NULL) {
4422            userId = UserHandle.getUserId(sourceRecord.app.uid);
4423        }
4424
4425        // TODO: Switch to user app stacks here.
4426        try {
4427            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4428                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4429                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4430            return ret;
4431        } catch (SecurityException e) {
4432            // XXX need to figure out how to propagate to original app.
4433            // A SecurityException here is generally actually a fault of the original
4434            // calling activity (such as a fairly granting permissions), so propagate it
4435            // back to them.
4436            /*
4437            StringBuilder msg = new StringBuilder();
4438            msg.append("While launching");
4439            msg.append(intent.toString());
4440            msg.append(": ");
4441            msg.append(e.getMessage());
4442            */
4443            throw e;
4444        }
4445    }
4446
4447    @Override
4448    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4449            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4450            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4451        enforceNotIsolatedCaller("startActivityAndWait");
4452        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4453                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4454        WaitResult res = new WaitResult();
4455        // TODO: Switch to user app stacks here.
4456        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4457                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4458                bOptions, false, userId, null, null);
4459        return res;
4460    }
4461
4462    @Override
4463    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4464            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4465            int startFlags, Configuration config, Bundle bOptions, int userId) {
4466        enforceNotIsolatedCaller("startActivityWithConfig");
4467        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4468                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4469        // TODO: Switch to user app stacks here.
4470        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4471                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4472                null, null, config, bOptions, false, userId, null, null);
4473        return ret;
4474    }
4475
4476    @Override
4477    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4478            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4479            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4480            throws TransactionTooLargeException {
4481        enforceNotIsolatedCaller("startActivityIntentSender");
4482        // Refuse possible leaked file descriptors
4483        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4484            throw new IllegalArgumentException("File descriptors passed in Intent");
4485        }
4486
4487        IIntentSender sender = intent.getTarget();
4488        if (!(sender instanceof PendingIntentRecord)) {
4489            throw new IllegalArgumentException("Bad PendingIntent object");
4490        }
4491
4492        PendingIntentRecord pir = (PendingIntentRecord)sender;
4493
4494        synchronized (this) {
4495            // If this is coming from the currently resumed activity, it is
4496            // effectively saying that app switches are allowed at this point.
4497            final ActivityStack stack = getFocusedStack();
4498            if (stack.mResumedActivity != null &&
4499                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4500                mAppSwitchesAllowedTime = 0;
4501            }
4502        }
4503        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4504                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4505        return ret;
4506    }
4507
4508    @Override
4509    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4510            Intent intent, String resolvedType, IVoiceInteractionSession session,
4511            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4512            Bundle bOptions, int userId) {
4513        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4514                != PackageManager.PERMISSION_GRANTED) {
4515            String msg = "Permission Denial: startVoiceActivity() from pid="
4516                    + Binder.getCallingPid()
4517                    + ", uid=" + Binder.getCallingUid()
4518                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4519            Slog.w(TAG, msg);
4520            throw new SecurityException(msg);
4521        }
4522        if (session == null || interactor == null) {
4523            throw new NullPointerException("null session or interactor");
4524        }
4525        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4526                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4527        // TODO: Switch to user app stacks here.
4528        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4529                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4530                null, bOptions, false, userId, null, null);
4531    }
4532
4533    @Override
4534    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4535            throws RemoteException {
4536        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4537        synchronized (this) {
4538            ActivityRecord activity = getFocusedStack().topActivity();
4539            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4540                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4541            }
4542            if (mRunningVoice != null || activity.task.voiceSession != null
4543                    || activity.voiceSession != null) {
4544                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4545                return;
4546            }
4547            if (activity.pendingVoiceInteractionStart) {
4548                Slog.w(TAG, "Pending start of voice interaction already.");
4549                return;
4550            }
4551            activity.pendingVoiceInteractionStart = true;
4552        }
4553        LocalServices.getService(VoiceInteractionManagerInternal.class)
4554                .startLocalVoiceInteraction(callingActivity, options);
4555    }
4556
4557    @Override
4558    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4559        LocalServices.getService(VoiceInteractionManagerInternal.class)
4560                .stopLocalVoiceInteraction(callingActivity);
4561    }
4562
4563    @Override
4564    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4565        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4566                .supportsLocalVoiceInteraction();
4567    }
4568
4569    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4570            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4571        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4572        if (activityToCallback == null) return;
4573        activityToCallback.setVoiceSessionLocked(voiceSession);
4574
4575        // Inform the activity
4576        try {
4577            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4578                    voiceInteractor);
4579            long token = Binder.clearCallingIdentity();
4580            try {
4581                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4582            } finally {
4583                Binder.restoreCallingIdentity(token);
4584            }
4585            // TODO: VI Should we cache the activity so that it's easier to find later
4586            // rather than scan through all the stacks and activities?
4587        } catch (RemoteException re) {
4588            activityToCallback.clearVoiceSessionLocked();
4589            // TODO: VI Should this terminate the voice session?
4590        }
4591    }
4592
4593    @Override
4594    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4595        synchronized (this) {
4596            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4597                if (keepAwake) {
4598                    mVoiceWakeLock.acquire();
4599                } else {
4600                    mVoiceWakeLock.release();
4601                }
4602            }
4603        }
4604    }
4605
4606    @Override
4607    public boolean startNextMatchingActivity(IBinder callingActivity,
4608            Intent intent, Bundle bOptions) {
4609        // Refuse possible leaked file descriptors
4610        if (intent != null && intent.hasFileDescriptors() == true) {
4611            throw new IllegalArgumentException("File descriptors passed in Intent");
4612        }
4613        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4614
4615        synchronized (this) {
4616            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4617            if (r == null) {
4618                ActivityOptions.abort(options);
4619                return false;
4620            }
4621            if (r.app == null || r.app.thread == null) {
4622                // The caller is not running...  d'oh!
4623                ActivityOptions.abort(options);
4624                return false;
4625            }
4626            intent = new Intent(intent);
4627            // The caller is not allowed to change the data.
4628            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4629            // And we are resetting to find the next component...
4630            intent.setComponent(null);
4631
4632            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4633
4634            ActivityInfo aInfo = null;
4635            try {
4636                List<ResolveInfo> resolves =
4637                    AppGlobals.getPackageManager().queryIntentActivities(
4638                            intent, r.resolvedType,
4639                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4640                            UserHandle.getCallingUserId()).getList();
4641
4642                // Look for the original activity in the list...
4643                final int N = resolves != null ? resolves.size() : 0;
4644                for (int i=0; i<N; i++) {
4645                    ResolveInfo rInfo = resolves.get(i);
4646                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4647                            && rInfo.activityInfo.name.equals(r.info.name)) {
4648                        // We found the current one...  the next matching is
4649                        // after it.
4650                        i++;
4651                        if (i<N) {
4652                            aInfo = resolves.get(i).activityInfo;
4653                        }
4654                        if (debug) {
4655                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4656                                    + "/" + r.info.name);
4657                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4658                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4659                        }
4660                        break;
4661                    }
4662                }
4663            } catch (RemoteException e) {
4664            }
4665
4666            if (aInfo == null) {
4667                // Nobody who is next!
4668                ActivityOptions.abort(options);
4669                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4670                return false;
4671            }
4672
4673            intent.setComponent(new ComponentName(
4674                    aInfo.applicationInfo.packageName, aInfo.name));
4675            intent.setFlags(intent.getFlags()&~(
4676                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4677                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4678                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4679                    Intent.FLAG_ACTIVITY_NEW_TASK));
4680
4681            // Okay now we need to start the new activity, replacing the
4682            // currently running activity.  This is a little tricky because
4683            // we want to start the new one as if the current one is finished,
4684            // but not finish the current one first so that there is no flicker.
4685            // And thus...
4686            final boolean wasFinishing = r.finishing;
4687            r.finishing = true;
4688
4689            // Propagate reply information over to the new activity.
4690            final ActivityRecord resultTo = r.resultTo;
4691            final String resultWho = r.resultWho;
4692            final int requestCode = r.requestCode;
4693            r.resultTo = null;
4694            if (resultTo != null) {
4695                resultTo.removeResultsLocked(r, resultWho, requestCode);
4696            }
4697
4698            final long origId = Binder.clearCallingIdentity();
4699            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4700                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4701                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4702                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4703                    false, false, null, null, null);
4704            Binder.restoreCallingIdentity(origId);
4705
4706            r.finishing = wasFinishing;
4707            if (res != ActivityManager.START_SUCCESS) {
4708                return false;
4709            }
4710            return true;
4711        }
4712    }
4713
4714    @Override
4715    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4716        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4717            String msg = "Permission Denial: startActivityFromRecents called without " +
4718                    START_TASKS_FROM_RECENTS;
4719            Slog.w(TAG, msg);
4720            throw new SecurityException(msg);
4721        }
4722        final long origId = Binder.clearCallingIdentity();
4723        try {
4724            synchronized (this) {
4725                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4726            }
4727        } finally {
4728            Binder.restoreCallingIdentity(origId);
4729        }
4730    }
4731
4732    final int startActivityInPackage(int uid, String callingPackage,
4733            Intent intent, String resolvedType, IBinder resultTo,
4734            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4735            IActivityContainer container, TaskRecord inTask) {
4736
4737        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4738                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4739
4740        // TODO: Switch to user app stacks here.
4741        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4742                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4743                null, null, null, bOptions, false, userId, container, inTask);
4744        return ret;
4745    }
4746
4747    @Override
4748    public final int startActivities(IApplicationThread caller, String callingPackage,
4749            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4750            int userId) {
4751        enforceNotIsolatedCaller("startActivities");
4752        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4753                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4754        // TODO: Switch to user app stacks here.
4755        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4756                resolvedTypes, resultTo, bOptions, userId);
4757        return ret;
4758    }
4759
4760    final int startActivitiesInPackage(int uid, String callingPackage,
4761            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4762            Bundle bOptions, int userId) {
4763
4764        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4765                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4766        // TODO: Switch to user app stacks here.
4767        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4768                resultTo, bOptions, userId);
4769        return ret;
4770    }
4771
4772    @Override
4773    public void reportActivityFullyDrawn(IBinder token) {
4774        synchronized (this) {
4775            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4776            if (r == null) {
4777                return;
4778            }
4779            r.reportFullyDrawnLocked();
4780        }
4781    }
4782
4783    @Override
4784    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4785        synchronized (this) {
4786            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4787            if (r == null) {
4788                return;
4789            }
4790            TaskRecord task = r.task;
4791            if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4792                // Fixed screen orientation isn't supported when activities aren't in full screen
4793                // mode.
4794                return;
4795            }
4796            final long origId = Binder.clearCallingIdentity();
4797            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4798            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4799                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4800            if (config != null) {
4801                r.frozenBeforeDestroy = true;
4802                if (!updateConfigurationLocked(config, r, false)) {
4803                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
4804                }
4805            }
4806            Binder.restoreCallingIdentity(origId);
4807        }
4808    }
4809
4810    @Override
4811    public int getRequestedOrientation(IBinder token) {
4812        synchronized (this) {
4813            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4814            if (r == null) {
4815                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4816            }
4817            return mWindowManager.getAppOrientation(r.appToken);
4818        }
4819    }
4820
4821    /**
4822     * This is the internal entry point for handling Activity.finish().
4823     *
4824     * @param token The Binder token referencing the Activity we want to finish.
4825     * @param resultCode Result code, if any, from this Activity.
4826     * @param resultData Result data (Intent), if any, from this Activity.
4827     * @param finishTask Whether to finish the task associated with this Activity.
4828     *
4829     * @return Returns true if the activity successfully finished, or false if it is still running.
4830     */
4831    @Override
4832    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4833            int finishTask) {
4834        // Refuse possible leaked file descriptors
4835        if (resultData != null && resultData.hasFileDescriptors() == true) {
4836            throw new IllegalArgumentException("File descriptors passed in Intent");
4837        }
4838
4839        synchronized(this) {
4840            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4841            if (r == null) {
4842                return true;
4843            }
4844            // Keep track of the root activity of the task before we finish it
4845            TaskRecord tr = r.task;
4846            ActivityRecord rootR = tr.getRootActivity();
4847            if (rootR == null) {
4848                Slog.w(TAG, "Finishing task with all activities already finished");
4849            }
4850            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4851            // finish.
4852            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4853                    mStackSupervisor.isLastLockedTask(tr)) {
4854                Slog.i(TAG, "Not finishing task in lock task mode");
4855                mStackSupervisor.showLockTaskToast();
4856                return false;
4857            }
4858            if (mController != null) {
4859                // Find the first activity that is not finishing.
4860                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4861                if (next != null) {
4862                    // ask watcher if this is allowed
4863                    boolean resumeOK = true;
4864                    try {
4865                        resumeOK = mController.activityResuming(next.packageName);
4866                    } catch (RemoteException e) {
4867                        mController = null;
4868                        Watchdog.getInstance().setActivityController(null);
4869                    }
4870
4871                    if (!resumeOK) {
4872                        Slog.i(TAG, "Not finishing activity because controller resumed");
4873                        return false;
4874                    }
4875                }
4876            }
4877            final long origId = Binder.clearCallingIdentity();
4878            try {
4879                boolean res;
4880                final boolean finishWithRootActivity =
4881                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4882                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4883                        || (finishWithRootActivity && r == rootR)) {
4884                    // If requested, remove the task that is associated to this activity only if it
4885                    // was the root activity in the task. The result code and data is ignored
4886                    // because we don't support returning them across task boundaries. Also, to
4887                    // keep backwards compatibility we remove the task from recents when finishing
4888                    // task with root activity.
4889                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4890                    if (!res) {
4891                        Slog.i(TAG, "Removing task failed to finish activity");
4892                    }
4893                } else {
4894                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4895                            resultData, "app-request", true);
4896                    if (!res) {
4897                        Slog.i(TAG, "Failed to finish by app-request");
4898                    }
4899                }
4900                return res;
4901            } finally {
4902                Binder.restoreCallingIdentity(origId);
4903            }
4904        }
4905    }
4906
4907    @Override
4908    public final void finishHeavyWeightApp() {
4909        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4910                != PackageManager.PERMISSION_GRANTED) {
4911            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4912                    + Binder.getCallingPid()
4913                    + ", uid=" + Binder.getCallingUid()
4914                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4915            Slog.w(TAG, msg);
4916            throw new SecurityException(msg);
4917        }
4918
4919        synchronized(this) {
4920            if (mHeavyWeightProcess == null) {
4921                return;
4922            }
4923
4924            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4925            for (int i = 0; i < activities.size(); i++) {
4926                ActivityRecord r = activities.get(i);
4927                if (!r.finishing && r.isInStackLocked()) {
4928                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4929                            null, "finish-heavy", true);
4930                }
4931            }
4932
4933            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4934                    mHeavyWeightProcess.userId, 0));
4935            mHeavyWeightProcess = null;
4936        }
4937    }
4938
4939    @Override
4940    public void crashApplication(int uid, int initialPid, String packageName,
4941            String message) {
4942        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4943                != PackageManager.PERMISSION_GRANTED) {
4944            String msg = "Permission Denial: crashApplication() from pid="
4945                    + Binder.getCallingPid()
4946                    + ", uid=" + Binder.getCallingUid()
4947                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4948            Slog.w(TAG, msg);
4949            throw new SecurityException(msg);
4950        }
4951
4952        synchronized(this) {
4953            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4954        }
4955    }
4956
4957    @Override
4958    public final void finishSubActivity(IBinder token, String resultWho,
4959            int requestCode) {
4960        synchronized(this) {
4961            final long origId = Binder.clearCallingIdentity();
4962            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4963            if (r != null) {
4964                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4965            }
4966            Binder.restoreCallingIdentity(origId);
4967        }
4968    }
4969
4970    @Override
4971    public boolean finishActivityAffinity(IBinder token) {
4972        synchronized(this) {
4973            final long origId = Binder.clearCallingIdentity();
4974            try {
4975                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4976                if (r == null) {
4977                    return false;
4978                }
4979
4980                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4981                // can finish.
4982                final TaskRecord task = r.task;
4983                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4984                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4985                    mStackSupervisor.showLockTaskToast();
4986                    return false;
4987                }
4988                return task.stack.finishActivityAffinityLocked(r);
4989            } finally {
4990                Binder.restoreCallingIdentity(origId);
4991            }
4992        }
4993    }
4994
4995    @Override
4996    public void finishVoiceTask(IVoiceInteractionSession session) {
4997        synchronized (this) {
4998            final long origId = Binder.clearCallingIdentity();
4999            try {
5000                // TODO: VI Consider treating local voice interactions and voice tasks
5001                // differently here
5002                mStackSupervisor.finishVoiceTask(session);
5003            } finally {
5004                Binder.restoreCallingIdentity(origId);
5005            }
5006        }
5007
5008    }
5009
5010    @Override
5011    public boolean releaseActivityInstance(IBinder token) {
5012        synchronized(this) {
5013            final long origId = Binder.clearCallingIdentity();
5014            try {
5015                ActivityRecord r = ActivityRecord.isInStackLocked(token);
5016                if (r == null) {
5017                    return false;
5018                }
5019                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
5020            } finally {
5021                Binder.restoreCallingIdentity(origId);
5022            }
5023        }
5024    }
5025
5026    @Override
5027    public void releaseSomeActivities(IApplicationThread appInt) {
5028        synchronized(this) {
5029            final long origId = Binder.clearCallingIdentity();
5030            try {
5031                ProcessRecord app = getRecordForAppLocked(appInt);
5032                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5033            } finally {
5034                Binder.restoreCallingIdentity(origId);
5035            }
5036        }
5037    }
5038
5039    @Override
5040    public boolean willActivityBeVisible(IBinder token) {
5041        synchronized(this) {
5042            ActivityStack stack = ActivityRecord.getStackLocked(token);
5043            if (stack != null) {
5044                return stack.willActivityBeVisibleLocked(token);
5045            }
5046            return false;
5047        }
5048    }
5049
5050    @Override
5051    public void overridePendingTransition(IBinder token, String packageName,
5052            int enterAnim, int exitAnim) {
5053        synchronized(this) {
5054            ActivityRecord self = ActivityRecord.isInStackLocked(token);
5055            if (self == null) {
5056                return;
5057            }
5058
5059            final long origId = Binder.clearCallingIdentity();
5060
5061            if (self.state == ActivityState.RESUMED
5062                    || self.state == ActivityState.PAUSING) {
5063                mWindowManager.overridePendingAppTransition(packageName,
5064                        enterAnim, exitAnim, null);
5065            }
5066
5067            Binder.restoreCallingIdentity(origId);
5068        }
5069    }
5070
5071    /**
5072     * Main function for removing an existing process from the activity manager
5073     * as a result of that process going away.  Clears out all connections
5074     * to the process.
5075     */
5076    private final void handleAppDiedLocked(ProcessRecord app,
5077            boolean restarting, boolean allowRestart) {
5078        int pid = app.pid;
5079        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5080                false /*replacingPid*/);
5081        if (!kept && !restarting) {
5082            removeLruProcessLocked(app);
5083            if (pid > 0) {
5084                ProcessList.remove(pid);
5085            }
5086        }
5087
5088        if (mProfileProc == app) {
5089            clearProfilerLocked();
5090        }
5091
5092        // Remove this application's activities from active lists.
5093        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5094
5095        app.activities.clear();
5096
5097        if (app.instrumentationClass != null) {
5098            Slog.w(TAG, "Crash of app " + app.processName
5099                  + " running instrumentation " + app.instrumentationClass);
5100            Bundle info = new Bundle();
5101            info.putString("shortMsg", "Process crashed.");
5102            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5103        }
5104
5105        if (!restarting && hasVisibleActivities
5106                && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5107            // If there was nothing to resume, and we are not already restarting this process, but
5108            // there is a visible activity that is hosted by the process...  then make sure all
5109            // visible activities are running, taking care of restarting this process.
5110            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5111        }
5112    }
5113
5114    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5115        IBinder threadBinder = thread.asBinder();
5116        // Find the application record.
5117        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5118            ProcessRecord rec = mLruProcesses.get(i);
5119            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5120                return i;
5121            }
5122        }
5123        return -1;
5124    }
5125
5126    final ProcessRecord getRecordForAppLocked(
5127            IApplicationThread thread) {
5128        if (thread == null) {
5129            return null;
5130        }
5131
5132        int appIndex = getLRURecordIndexForAppLocked(thread);
5133        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
5134    }
5135
5136    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5137        // If there are no longer any background processes running,
5138        // and the app that died was not running instrumentation,
5139        // then tell everyone we are now low on memory.
5140        boolean haveBg = false;
5141        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5142            ProcessRecord rec = mLruProcesses.get(i);
5143            if (rec.thread != null
5144                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5145                haveBg = true;
5146                break;
5147            }
5148        }
5149
5150        if (!haveBg) {
5151            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5152            if (doReport) {
5153                long now = SystemClock.uptimeMillis();
5154                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5155                    doReport = false;
5156                } else {
5157                    mLastMemUsageReportTime = now;
5158                }
5159            }
5160            final ArrayList<ProcessMemInfo> memInfos
5161                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5162            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5163            long now = SystemClock.uptimeMillis();
5164            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5165                ProcessRecord rec = mLruProcesses.get(i);
5166                if (rec == dyingProc || rec.thread == null) {
5167                    continue;
5168                }
5169                if (doReport) {
5170                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5171                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5172                }
5173                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5174                    // The low memory report is overriding any current
5175                    // state for a GC request.  Make sure to do
5176                    // heavy/important/visible/foreground processes first.
5177                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5178                        rec.lastRequestedGc = 0;
5179                    } else {
5180                        rec.lastRequestedGc = rec.lastLowMemory;
5181                    }
5182                    rec.reportLowMemory = true;
5183                    rec.lastLowMemory = now;
5184                    mProcessesToGc.remove(rec);
5185                    addProcessToGcListLocked(rec);
5186                }
5187            }
5188            if (doReport) {
5189                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5190                mHandler.sendMessage(msg);
5191            }
5192            scheduleAppGcsLocked();
5193        }
5194    }
5195
5196    final void appDiedLocked(ProcessRecord app) {
5197       appDiedLocked(app, app.pid, app.thread, false);
5198    }
5199
5200    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5201            boolean fromBinderDied) {
5202        // First check if this ProcessRecord is actually active for the pid.
5203        synchronized (mPidsSelfLocked) {
5204            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5205            if (curProc != app) {
5206                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5207                return;
5208            }
5209        }
5210
5211        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5212        synchronized (stats) {
5213            stats.noteProcessDiedLocked(app.info.uid, pid);
5214        }
5215
5216        if (!app.killed) {
5217            if (!fromBinderDied) {
5218                Process.killProcessQuiet(pid);
5219            }
5220            killProcessGroup(app.uid, pid);
5221            app.killed = true;
5222        }
5223
5224        // Clean up already done if the process has been re-started.
5225        if (app.pid == pid && app.thread != null &&
5226                app.thread.asBinder() == thread.asBinder()) {
5227            boolean doLowMem = app.instrumentationClass == null;
5228            boolean doOomAdj = doLowMem;
5229            if (!app.killedByAm) {
5230                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5231                        + ") has died");
5232                mAllowLowerMemLevel = true;
5233            } else {
5234                // Note that we always want to do oom adj to update our state with the
5235                // new number of procs.
5236                mAllowLowerMemLevel = false;
5237                doLowMem = false;
5238            }
5239            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5240            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5241                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5242            handleAppDiedLocked(app, false, true);
5243
5244            if (doOomAdj) {
5245                updateOomAdjLocked();
5246            }
5247            if (doLowMem) {
5248                doLowMemReportIfNeededLocked(app);
5249            }
5250        } else if (app.pid != pid) {
5251            // A new process has already been started.
5252            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5253                    + ") has died and restarted (pid " + app.pid + ").");
5254            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5255        } else if (DEBUG_PROCESSES) {
5256            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5257                    + thread.asBinder());
5258        }
5259    }
5260
5261    /**
5262     * If a stack trace dump file is configured, dump process stack traces.
5263     * @param clearTraces causes the dump file to be erased prior to the new
5264     *    traces being written, if true; when false, the new traces will be
5265     *    appended to any existing file content.
5266     * @param firstPids of dalvik VM processes to dump stack traces for first
5267     * @param lastPids of dalvik VM processes to dump stack traces for last
5268     * @param nativeProcs optional list of native process names to dump stack crawls
5269     * @return file containing stack traces, or null if no dump file is configured
5270     */
5271    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5272            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5273        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5274        if (tracesPath == null || tracesPath.length() == 0) {
5275            return null;
5276        }
5277
5278        File tracesFile = new File(tracesPath);
5279        try {
5280            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5281            tracesFile.createNewFile();
5282            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5283        } catch (IOException e) {
5284            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5285            return null;
5286        }
5287
5288        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5289        return tracesFile;
5290    }
5291
5292    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5293            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5294        // Use a FileObserver to detect when traces finish writing.
5295        // The order of traces is considered important to maintain for legibility.
5296        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5297            @Override
5298            public synchronized void onEvent(int event, String path) { notify(); }
5299        };
5300
5301        try {
5302            observer.startWatching();
5303
5304            // First collect all of the stacks of the most important pids.
5305            if (firstPids != null) {
5306                try {
5307                    int num = firstPids.size();
5308                    for (int i = 0; i < num; i++) {
5309                        synchronized (observer) {
5310                            if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5311                                    + firstPids.get(i));
5312                            final long sime = SystemClock.elapsedRealtime();
5313                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5314                            observer.wait(1000);  // Wait for write-close, give up after 1 sec
5315                            if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5316                                    + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5317                        }
5318                    }
5319                } catch (InterruptedException e) {
5320                    Slog.wtf(TAG, e);
5321                }
5322            }
5323
5324            // Next collect the stacks of the native pids
5325            if (nativeProcs != null) {
5326                int[] pids = Process.getPidsForCommands(nativeProcs);
5327                if (pids != null) {
5328                    for (int pid : pids) {
5329                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5330                        final long sime = SystemClock.elapsedRealtime();
5331                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5332                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5333                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5334                    }
5335                }
5336            }
5337
5338            // Lastly, measure CPU usage.
5339            if (processCpuTracker != null) {
5340                processCpuTracker.init();
5341                System.gc();
5342                processCpuTracker.update();
5343                try {
5344                    synchronized (processCpuTracker) {
5345                        processCpuTracker.wait(500); // measure over 1/2 second.
5346                    }
5347                } catch (InterruptedException e) {
5348                }
5349                processCpuTracker.update();
5350
5351                // We'll take the stack crawls of just the top apps using CPU.
5352                final int N = processCpuTracker.countWorkingStats();
5353                int numProcs = 0;
5354                for (int i=0; i<N && numProcs<5; i++) {
5355                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5356                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5357                        numProcs++;
5358                        try {
5359                            synchronized (observer) {
5360                                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5361                                        + stats.pid);
5362                                final long stime = SystemClock.elapsedRealtime();
5363                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5364                                observer.wait(1000);  // Wait for write-close, give up after 1 sec
5365                                if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5366                                        + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5367                            }
5368                        } catch (InterruptedException e) {
5369                            Slog.wtf(TAG, e);
5370                        }
5371                    } else if (DEBUG_ANR) {
5372                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5373                                + stats.pid);
5374                    }
5375                }
5376            }
5377        } finally {
5378            observer.stopWatching();
5379        }
5380    }
5381
5382    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5383        if (true || IS_USER_BUILD) {
5384            return;
5385        }
5386        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5387        if (tracesPath == null || tracesPath.length() == 0) {
5388            return;
5389        }
5390
5391        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5392        StrictMode.allowThreadDiskWrites();
5393        try {
5394            final File tracesFile = new File(tracesPath);
5395            final File tracesDir = tracesFile.getParentFile();
5396            final File tracesTmp = new File(tracesDir, "__tmp__");
5397            try {
5398                if (tracesFile.exists()) {
5399                    tracesTmp.delete();
5400                    tracesFile.renameTo(tracesTmp);
5401                }
5402                StringBuilder sb = new StringBuilder();
5403                Time tobj = new Time();
5404                tobj.set(System.currentTimeMillis());
5405                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5406                sb.append(": ");
5407                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5408                sb.append(" since ");
5409                sb.append(msg);
5410                FileOutputStream fos = new FileOutputStream(tracesFile);
5411                fos.write(sb.toString().getBytes());
5412                if (app == null) {
5413                    fos.write("\n*** No application process!".getBytes());
5414                }
5415                fos.close();
5416                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5417            } catch (IOException e) {
5418                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5419                return;
5420            }
5421
5422            if (app != null) {
5423                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5424                firstPids.add(app.pid);
5425                dumpStackTraces(tracesPath, firstPids, null, null, null);
5426            }
5427
5428            File lastTracesFile = null;
5429            File curTracesFile = null;
5430            for (int i=9; i>=0; i--) {
5431                String name = String.format(Locale.US, "slow%02d.txt", i);
5432                curTracesFile = new File(tracesDir, name);
5433                if (curTracesFile.exists()) {
5434                    if (lastTracesFile != null) {
5435                        curTracesFile.renameTo(lastTracesFile);
5436                    } else {
5437                        curTracesFile.delete();
5438                    }
5439                }
5440                lastTracesFile = curTracesFile;
5441            }
5442            tracesFile.renameTo(curTracesFile);
5443            if (tracesTmp.exists()) {
5444                tracesTmp.renameTo(tracesFile);
5445            }
5446        } finally {
5447            StrictMode.setThreadPolicy(oldPolicy);
5448        }
5449    }
5450
5451    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5452        if (!mLaunchWarningShown) {
5453            mLaunchWarningShown = true;
5454            mUiHandler.post(new Runnable() {
5455                @Override
5456                public void run() {
5457                    synchronized (ActivityManagerService.this) {
5458                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5459                        d.show();
5460                        mUiHandler.postDelayed(new Runnable() {
5461                            @Override
5462                            public void run() {
5463                                synchronized (ActivityManagerService.this) {
5464                                    d.dismiss();
5465                                    mLaunchWarningShown = false;
5466                                }
5467                            }
5468                        }, 4000);
5469                    }
5470                }
5471            });
5472        }
5473    }
5474
5475    @Override
5476    public boolean clearApplicationUserData(final String packageName,
5477            final IPackageDataObserver observer, int userId) {
5478        enforceNotIsolatedCaller("clearApplicationUserData");
5479        int uid = Binder.getCallingUid();
5480        int pid = Binder.getCallingPid();
5481        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5482                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5483
5484
5485        long callingId = Binder.clearCallingIdentity();
5486        try {
5487            IPackageManager pm = AppGlobals.getPackageManager();
5488            int pkgUid = -1;
5489            synchronized(this) {
5490                if (getPackageManagerInternalLocked().isPackageDataProtected(
5491                        userId, packageName)) {
5492                    throw new SecurityException(
5493                            "Cannot clear data for a protected package: " + packageName);
5494                }
5495
5496                try {
5497                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5498                } catch (RemoteException e) {
5499                }
5500                if (pkgUid == -1) {
5501                    Slog.w(TAG, "Invalid packageName: " + packageName);
5502                    if (observer != null) {
5503                        try {
5504                            observer.onRemoveCompleted(packageName, false);
5505                        } catch (RemoteException e) {
5506                            Slog.i(TAG, "Observer no longer exists.");
5507                        }
5508                    }
5509                    return false;
5510                }
5511                if (uid == pkgUid || checkComponentPermission(
5512                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5513                        pid, uid, -1, true)
5514                        == PackageManager.PERMISSION_GRANTED) {
5515                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5516                } else {
5517                    throw new SecurityException("PID " + pid + " does not have permission "
5518                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5519                                    + " of package " + packageName);
5520                }
5521
5522                // Remove all tasks match the cleared application package and user
5523                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5524                    final TaskRecord tr = mRecentTasks.get(i);
5525                    final String taskPackageName =
5526                            tr.getBaseIntent().getComponent().getPackageName();
5527                    if (tr.userId != userId) continue;
5528                    if (!taskPackageName.equals(packageName)) continue;
5529                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5530                }
5531            }
5532
5533            final int pkgUidF = pkgUid;
5534            final int userIdF = userId;
5535            final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5536                @Override
5537                public void onRemoveCompleted(String packageName, boolean succeeded)
5538                        throws RemoteException {
5539                    synchronized (ActivityManagerService.this) {
5540                        finishForceStopPackageLocked(packageName, pkgUidF);
5541                    }
5542
5543                    final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5544                            Uri.fromParts("package", packageName, null));
5545                    intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5546                    intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5547                    broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5548                            null, null, 0, null, null, null, null, false, false, userIdF);
5549
5550                    if (observer != null) {
5551                        observer.onRemoveCompleted(packageName, succeeded);
5552                    }
5553                }
5554            };
5555
5556            try {
5557                // Clear application user data
5558                pm.clearApplicationUserData(packageName, localObserver, userId);
5559
5560                synchronized(this) {
5561                    // Remove all permissions granted from/to this package
5562                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5563                }
5564
5565                // Remove all zen rules created by this package; revoke it's zen access.
5566                INotificationManager inm = NotificationManager.getService();
5567                inm.removeAutomaticZenRules(packageName);
5568                inm.setNotificationPolicyAccessGranted(packageName, false);
5569
5570            } catch (RemoteException e) {
5571            }
5572        } finally {
5573            Binder.restoreCallingIdentity(callingId);
5574        }
5575        return true;
5576    }
5577
5578    @Override
5579    public void killBackgroundProcesses(final String packageName, int userId) {
5580        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5581                != PackageManager.PERMISSION_GRANTED &&
5582                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5583                        != PackageManager.PERMISSION_GRANTED) {
5584            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5585                    + Binder.getCallingPid()
5586                    + ", uid=" + Binder.getCallingUid()
5587                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5588            Slog.w(TAG, msg);
5589            throw new SecurityException(msg);
5590        }
5591
5592        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5593                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5594        long callingId = Binder.clearCallingIdentity();
5595        try {
5596            IPackageManager pm = AppGlobals.getPackageManager();
5597            synchronized(this) {
5598                int appId = -1;
5599                try {
5600                    appId = UserHandle.getAppId(
5601                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5602                } catch (RemoteException e) {
5603                }
5604                if (appId == -1) {
5605                    Slog.w(TAG, "Invalid packageName: " + packageName);
5606                    return;
5607                }
5608                killPackageProcessesLocked(packageName, appId, userId,
5609                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5610            }
5611        } finally {
5612            Binder.restoreCallingIdentity(callingId);
5613        }
5614    }
5615
5616    @Override
5617    public void killAllBackgroundProcesses() {
5618        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5619                != PackageManager.PERMISSION_GRANTED) {
5620            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5621                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5622                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5623            Slog.w(TAG, msg);
5624            throw new SecurityException(msg);
5625        }
5626
5627        final long callingId = Binder.clearCallingIdentity();
5628        try {
5629            synchronized (this) {
5630                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5631                final int NP = mProcessNames.getMap().size();
5632                for (int ip = 0; ip < NP; ip++) {
5633                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5634                    final int NA = apps.size();
5635                    for (int ia = 0; ia < NA; ia++) {
5636                        final ProcessRecord app = apps.valueAt(ia);
5637                        if (app.persistent) {
5638                            // We don't kill persistent processes.
5639                            continue;
5640                        }
5641                        if (app.removed) {
5642                            procs.add(app);
5643                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5644                            app.removed = true;
5645                            procs.add(app);
5646                        }
5647                    }
5648                }
5649
5650                final int N = procs.size();
5651                for (int i = 0; i < N; i++) {
5652                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5653                }
5654
5655                mAllowLowerMemLevel = true;
5656
5657                updateOomAdjLocked();
5658                doLowMemReportIfNeededLocked(null);
5659            }
5660        } finally {
5661            Binder.restoreCallingIdentity(callingId);
5662        }
5663    }
5664
5665    /**
5666     * Kills all background processes, except those matching any of the
5667     * specified properties.
5668     *
5669     * @param minTargetSdk the target SDK version at or above which to preserve
5670     *                     processes, or {@code -1} to ignore the target SDK
5671     * @param maxProcState the process state at or below which to preserve
5672     *                     processes, or {@code -1} to ignore the process state
5673     */
5674    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5675        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5676                != PackageManager.PERMISSION_GRANTED) {
5677            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5678                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5679                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5680            Slog.w(TAG, msg);
5681            throw new SecurityException(msg);
5682        }
5683
5684        final long callingId = Binder.clearCallingIdentity();
5685        try {
5686            synchronized (this) {
5687                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5688                final int NP = mProcessNames.getMap().size();
5689                for (int ip = 0; ip < NP; ip++) {
5690                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5691                    final int NA = apps.size();
5692                    for (int ia = 0; ia < NA; ia++) {
5693                        final ProcessRecord app = apps.valueAt(ia);
5694                        if (app.removed) {
5695                            procs.add(app);
5696                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5697                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5698                            app.removed = true;
5699                            procs.add(app);
5700                        }
5701                    }
5702                }
5703
5704                final int N = procs.size();
5705                for (int i = 0; i < N; i++) {
5706                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5707                }
5708            }
5709        } finally {
5710            Binder.restoreCallingIdentity(callingId);
5711        }
5712    }
5713
5714    @Override
5715    public void forceStopPackage(final String packageName, int userId) {
5716        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5717                != PackageManager.PERMISSION_GRANTED) {
5718            String msg = "Permission Denial: forceStopPackage() from pid="
5719                    + Binder.getCallingPid()
5720                    + ", uid=" + Binder.getCallingUid()
5721                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5722            Slog.w(TAG, msg);
5723            throw new SecurityException(msg);
5724        }
5725        final int callingPid = Binder.getCallingPid();
5726        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5727                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5728        long callingId = Binder.clearCallingIdentity();
5729        try {
5730            IPackageManager pm = AppGlobals.getPackageManager();
5731            synchronized(this) {
5732                int[] users = userId == UserHandle.USER_ALL
5733                        ? mUserController.getUsers() : new int[] { userId };
5734                for (int user : users) {
5735                    int pkgUid = -1;
5736                    try {
5737                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5738                                user);
5739                    } catch (RemoteException e) {
5740                    }
5741                    if (pkgUid == -1) {
5742                        Slog.w(TAG, "Invalid packageName: " + packageName);
5743                        continue;
5744                    }
5745                    try {
5746                        pm.setPackageStoppedState(packageName, true, user);
5747                    } catch (RemoteException e) {
5748                    } catch (IllegalArgumentException e) {
5749                        Slog.w(TAG, "Failed trying to unstop package "
5750                                + packageName + ": " + e);
5751                    }
5752                    if (mUserController.isUserRunningLocked(user, 0)) {
5753                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5754                        finishForceStopPackageLocked(packageName, pkgUid);
5755                    }
5756                }
5757            }
5758        } finally {
5759            Binder.restoreCallingIdentity(callingId);
5760        }
5761    }
5762
5763    @Override
5764    public void addPackageDependency(String packageName) {
5765        synchronized (this) {
5766            int callingPid = Binder.getCallingPid();
5767            if (callingPid == Process.myPid()) {
5768                //  Yeah, um, no.
5769                return;
5770            }
5771            ProcessRecord proc;
5772            synchronized (mPidsSelfLocked) {
5773                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5774            }
5775            if (proc != null) {
5776                if (proc.pkgDeps == null) {
5777                    proc.pkgDeps = new ArraySet<String>(1);
5778                }
5779                proc.pkgDeps.add(packageName);
5780            }
5781        }
5782    }
5783
5784    /*
5785     * The pkg name and app id have to be specified.
5786     */
5787    @Override
5788    public void killApplication(String pkg, int appId, int userId, String reason) {
5789        if (pkg == null) {
5790            return;
5791        }
5792        // Make sure the uid is valid.
5793        if (appId < 0) {
5794            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5795            return;
5796        }
5797        int callerUid = Binder.getCallingUid();
5798        // Only the system server can kill an application
5799        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5800            // Post an aysnc message to kill the application
5801            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5802            msg.arg1 = appId;
5803            msg.arg2 = userId;
5804            Bundle bundle = new Bundle();
5805            bundle.putString("pkg", pkg);
5806            bundle.putString("reason", reason);
5807            msg.obj = bundle;
5808            mHandler.sendMessage(msg);
5809        } else {
5810            throw new SecurityException(callerUid + " cannot kill pkg: " +
5811                    pkg);
5812        }
5813    }
5814
5815    @Override
5816    public void closeSystemDialogs(String reason) {
5817        enforceNotIsolatedCaller("closeSystemDialogs");
5818
5819        final int pid = Binder.getCallingPid();
5820        final int uid = Binder.getCallingUid();
5821        final long origId = Binder.clearCallingIdentity();
5822        try {
5823            synchronized (this) {
5824                // Only allow this from foreground processes, so that background
5825                // applications can't abuse it to prevent system UI from being shown.
5826                if (uid >= Process.FIRST_APPLICATION_UID) {
5827                    ProcessRecord proc;
5828                    synchronized (mPidsSelfLocked) {
5829                        proc = mPidsSelfLocked.get(pid);
5830                    }
5831                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5832                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5833                                + " from background process " + proc);
5834                        return;
5835                    }
5836                }
5837                closeSystemDialogsLocked(reason);
5838            }
5839        } finally {
5840            Binder.restoreCallingIdentity(origId);
5841        }
5842    }
5843
5844    void closeSystemDialogsLocked(String reason) {
5845        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5846        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5847                | Intent.FLAG_RECEIVER_FOREGROUND);
5848        if (reason != null) {
5849            intent.putExtra("reason", reason);
5850        }
5851        mWindowManager.closeSystemDialogs(reason);
5852
5853        mStackSupervisor.closeSystemDialogsLocked();
5854
5855        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5856                AppOpsManager.OP_NONE, null, false, false,
5857                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5858    }
5859
5860    @Override
5861    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5862        enforceNotIsolatedCaller("getProcessMemoryInfo");
5863        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5864        for (int i=pids.length-1; i>=0; i--) {
5865            ProcessRecord proc;
5866            int oomAdj;
5867            synchronized (this) {
5868                synchronized (mPidsSelfLocked) {
5869                    proc = mPidsSelfLocked.get(pids[i]);
5870                    oomAdj = proc != null ? proc.setAdj : 0;
5871                }
5872            }
5873            infos[i] = new Debug.MemoryInfo();
5874            Debug.getMemoryInfo(pids[i], infos[i]);
5875            if (proc != null) {
5876                synchronized (this) {
5877                    if (proc.thread != null && proc.setAdj == oomAdj) {
5878                        // Record this for posterity if the process has been stable.
5879                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5880                                infos[i].getTotalUss(), false, proc.pkgList);
5881                    }
5882                }
5883            }
5884        }
5885        return infos;
5886    }
5887
5888    @Override
5889    public long[] getProcessPss(int[] pids) {
5890        enforceNotIsolatedCaller("getProcessPss");
5891        long[] pss = new long[pids.length];
5892        for (int i=pids.length-1; i>=0; i--) {
5893            ProcessRecord proc;
5894            int oomAdj;
5895            synchronized (this) {
5896                synchronized (mPidsSelfLocked) {
5897                    proc = mPidsSelfLocked.get(pids[i]);
5898                    oomAdj = proc != null ? proc.setAdj : 0;
5899                }
5900            }
5901            long[] tmpUss = new long[1];
5902            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5903            if (proc != null) {
5904                synchronized (this) {
5905                    if (proc.thread != null && proc.setAdj == oomAdj) {
5906                        // Record this for posterity if the process has been stable.
5907                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5908                    }
5909                }
5910            }
5911        }
5912        return pss;
5913    }
5914
5915    @Override
5916    public void killApplicationProcess(String processName, int uid) {
5917        if (processName == null) {
5918            return;
5919        }
5920
5921        int callerUid = Binder.getCallingUid();
5922        // Only the system server can kill an application
5923        if (callerUid == Process.SYSTEM_UID) {
5924            synchronized (this) {
5925                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5926                if (app != null && app.thread != null) {
5927                    try {
5928                        app.thread.scheduleSuicide();
5929                    } catch (RemoteException e) {
5930                        // If the other end already died, then our work here is done.
5931                    }
5932                } else {
5933                    Slog.w(TAG, "Process/uid not found attempting kill of "
5934                            + processName + " / " + uid);
5935                }
5936            }
5937        } else {
5938            throw new SecurityException(callerUid + " cannot kill app process: " +
5939                    processName);
5940        }
5941    }
5942
5943    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5944        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5945                false, true, false, false, UserHandle.getUserId(uid), reason);
5946    }
5947
5948    private void finishForceStopPackageLocked(final String packageName, int uid) {
5949        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5950                Uri.fromParts("package", packageName, null));
5951        if (!mProcessesReady) {
5952            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5953                    | Intent.FLAG_RECEIVER_FOREGROUND);
5954        }
5955        intent.putExtra(Intent.EXTRA_UID, uid);
5956        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5957        broadcastIntentLocked(null, null, intent,
5958                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5959                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5960    }
5961
5962
5963    private final boolean killPackageProcessesLocked(String packageName, int appId,
5964            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5965            boolean doit, boolean evenPersistent, String reason) {
5966        ArrayList<ProcessRecord> procs = new ArrayList<>();
5967
5968        // Remove all processes this package may have touched: all with the
5969        // same UID (except for the system or root user), and all whose name
5970        // matches the package name.
5971        final int NP = mProcessNames.getMap().size();
5972        for (int ip=0; ip<NP; ip++) {
5973            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5974            final int NA = apps.size();
5975            for (int ia=0; ia<NA; ia++) {
5976                ProcessRecord app = apps.valueAt(ia);
5977                if (app.persistent && !evenPersistent) {
5978                    // we don't kill persistent processes
5979                    continue;
5980                }
5981                if (app.removed) {
5982                    if (doit) {
5983                        procs.add(app);
5984                    }
5985                    continue;
5986                }
5987
5988                // Skip process if it doesn't meet our oom adj requirement.
5989                if (app.setAdj < minOomAdj) {
5990                    continue;
5991                }
5992
5993                // If no package is specified, we call all processes under the
5994                // give user id.
5995                if (packageName == null) {
5996                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5997                        continue;
5998                    }
5999                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
6000                        continue;
6001                    }
6002                // Package has been specified, we want to hit all processes
6003                // that match it.  We need to qualify this by the processes
6004                // that are running under the specified app and user ID.
6005                } else {
6006                    final boolean isDep = app.pkgDeps != null
6007                            && app.pkgDeps.contains(packageName);
6008                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
6009                        continue;
6010                    }
6011                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
6012                        continue;
6013                    }
6014                    if (!app.pkgList.containsKey(packageName) && !isDep) {
6015                        continue;
6016                    }
6017                }
6018
6019                // Process has passed all conditions, kill it!
6020                if (!doit) {
6021                    return true;
6022                }
6023                app.removed = true;
6024                procs.add(app);
6025            }
6026        }
6027
6028        int N = procs.size();
6029        for (int i=0; i<N; i++) {
6030            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
6031        }
6032        updateOomAdjLocked();
6033        return N > 0;
6034    }
6035
6036    private void cleanupDisabledPackageComponentsLocked(
6037            String packageName, int userId, boolean killProcess, String[] changedClasses) {
6038
6039        Set<String> disabledClasses = null;
6040        boolean packageDisabled = false;
6041        IPackageManager pm = AppGlobals.getPackageManager();
6042
6043        if (changedClasses == null) {
6044            // Nothing changed...
6045            return;
6046        }
6047
6048        // Determine enable/disable state of the package and its components.
6049        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6050        for (int i = changedClasses.length - 1; i >= 0; i--) {
6051            final String changedClass = changedClasses[i];
6052
6053            if (changedClass.equals(packageName)) {
6054                try {
6055                    // Entire package setting changed
6056                    enabled = pm.getApplicationEnabledSetting(packageName,
6057                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6058                } catch (Exception e) {
6059                    // No such package/component; probably racing with uninstall.  In any
6060                    // event it means we have nothing further to do here.
6061                    return;
6062                }
6063                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6064                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6065                if (packageDisabled) {
6066                    // Entire package is disabled.
6067                    // No need to continue to check component states.
6068                    disabledClasses = null;
6069                    break;
6070                }
6071            } else {
6072                try {
6073                    enabled = pm.getComponentEnabledSetting(
6074                            new ComponentName(packageName, changedClass),
6075                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6076                } catch (Exception e) {
6077                    // As above, probably racing with uninstall.
6078                    return;
6079                }
6080                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6081                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6082                    if (disabledClasses == null) {
6083                        disabledClasses = new ArraySet<>(changedClasses.length);
6084                    }
6085                    disabledClasses.add(changedClass);
6086                }
6087            }
6088        }
6089
6090        if (!packageDisabled && disabledClasses == null) {
6091            // Nothing to do here...
6092            return;
6093        }
6094
6095        // Clean-up disabled activities.
6096        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6097                packageName, disabledClasses, true, false, userId) && mBooted) {
6098            mStackSupervisor.resumeFocusedStackTopActivityLocked();
6099            mStackSupervisor.scheduleIdleLocked();
6100        }
6101
6102        // Clean-up disabled tasks
6103        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6104
6105        // Clean-up disabled services.
6106        mServices.bringDownDisabledPackageServicesLocked(
6107                packageName, disabledClasses, userId, false, killProcess, true);
6108
6109        // Clean-up disabled providers.
6110        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6111        mProviderMap.collectPackageProvidersLocked(
6112                packageName, disabledClasses, true, false, userId, providers);
6113        for (int i = providers.size() - 1; i >= 0; i--) {
6114            removeDyingProviderLocked(null, providers.get(i), true);
6115        }
6116
6117        // Clean-up disabled broadcast receivers.
6118        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6119            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6120                    packageName, disabledClasses, userId, true);
6121        }
6122
6123    }
6124
6125    final boolean clearBroadcastQueueForUserLocked(int userId) {
6126        boolean didSomething = false;
6127        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6128            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6129                    null, null, userId, true);
6130        }
6131        return didSomething;
6132    }
6133
6134    final boolean forceStopPackageLocked(String packageName, int appId,
6135            boolean callerWillRestart, boolean purgeCache, boolean doit,
6136            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6137        int i;
6138
6139        if (userId == UserHandle.USER_ALL && packageName == null) {
6140            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6141        }
6142
6143        if (appId < 0 && packageName != null) {
6144            try {
6145                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6146                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6147            } catch (RemoteException e) {
6148            }
6149        }
6150
6151        if (doit) {
6152            if (packageName != null) {
6153                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6154                        + " user=" + userId + ": " + reason);
6155            } else {
6156                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6157            }
6158
6159            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6160        }
6161
6162        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6163                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6164                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6165
6166        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6167                packageName, null, doit, evenPersistent, userId)) {
6168            if (!doit) {
6169                return true;
6170            }
6171            didSomething = true;
6172        }
6173
6174        if (mServices.bringDownDisabledPackageServicesLocked(
6175                packageName, null, userId, evenPersistent, true, doit)) {
6176            if (!doit) {
6177                return true;
6178            }
6179            didSomething = true;
6180        }
6181
6182        if (packageName == null) {
6183            // Remove all sticky broadcasts from this user.
6184            mStickyBroadcasts.remove(userId);
6185        }
6186
6187        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6188        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6189                userId, providers)) {
6190            if (!doit) {
6191                return true;
6192            }
6193            didSomething = true;
6194        }
6195        for (i = providers.size() - 1; i >= 0; i--) {
6196            removeDyingProviderLocked(null, providers.get(i), true);
6197        }
6198
6199        // Remove transient permissions granted from/to this package/user
6200        removeUriPermissionsForPackageLocked(packageName, userId, false);
6201
6202        if (doit) {
6203            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6204                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6205                        packageName, null, userId, doit);
6206            }
6207        }
6208
6209        if (packageName == null || uninstalling) {
6210            // Remove pending intents.  For now we only do this when force
6211            // stopping users, because we have some problems when doing this
6212            // for packages -- app widgets are not currently cleaned up for
6213            // such packages, so they can be left with bad pending intents.
6214            if (mIntentSenderRecords.size() > 0) {
6215                Iterator<WeakReference<PendingIntentRecord>> it
6216                        = mIntentSenderRecords.values().iterator();
6217                while (it.hasNext()) {
6218                    WeakReference<PendingIntentRecord> wpir = it.next();
6219                    if (wpir == null) {
6220                        it.remove();
6221                        continue;
6222                    }
6223                    PendingIntentRecord pir = wpir.get();
6224                    if (pir == null) {
6225                        it.remove();
6226                        continue;
6227                    }
6228                    if (packageName == null) {
6229                        // Stopping user, remove all objects for the user.
6230                        if (pir.key.userId != userId) {
6231                            // Not the same user, skip it.
6232                            continue;
6233                        }
6234                    } else {
6235                        if (UserHandle.getAppId(pir.uid) != appId) {
6236                            // Different app id, skip it.
6237                            continue;
6238                        }
6239                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6240                            // Different user, skip it.
6241                            continue;
6242                        }
6243                        if (!pir.key.packageName.equals(packageName)) {
6244                            // Different package, skip it.
6245                            continue;
6246                        }
6247                    }
6248                    if (!doit) {
6249                        return true;
6250                    }
6251                    didSomething = true;
6252                    it.remove();
6253                    pir.canceled = true;
6254                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6255                        pir.key.activity.pendingResults.remove(pir.ref);
6256                    }
6257                }
6258            }
6259        }
6260
6261        if (doit) {
6262            if (purgeCache && packageName != null) {
6263                AttributeCache ac = AttributeCache.instance();
6264                if (ac != null) {
6265                    ac.removePackage(packageName);
6266                }
6267            }
6268            if (mBooted) {
6269                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6270                mStackSupervisor.scheduleIdleLocked();
6271            }
6272        }
6273
6274        return didSomething;
6275    }
6276
6277    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6278        ProcessRecord old = mProcessNames.remove(name, uid);
6279        if (old != null) {
6280            old.uidRecord.numProcs--;
6281            if (old.uidRecord.numProcs == 0) {
6282                // No more processes using this uid, tell clients it is gone.
6283                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6284                        "No more processes in " + old.uidRecord);
6285                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6286                mActiveUids.remove(uid);
6287                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6288            }
6289            old.uidRecord = null;
6290        }
6291        mIsolatedProcesses.remove(uid);
6292        return old;
6293    }
6294
6295    private final void addProcessNameLocked(ProcessRecord proc) {
6296        // We shouldn't already have a process under this name, but just in case we
6297        // need to clean up whatever may be there now.
6298        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6299        if (old == proc && proc.persistent) {
6300            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6301            Slog.w(TAG, "Re-adding persistent process " + proc);
6302        } else if (old != null) {
6303            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6304        }
6305        UidRecord uidRec = mActiveUids.get(proc.uid);
6306        if (uidRec == null) {
6307            uidRec = new UidRecord(proc.uid);
6308            // This is the first appearance of the uid, report it now!
6309            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6310                    "Creating new process uid: " + uidRec);
6311            mActiveUids.put(proc.uid, uidRec);
6312            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6313            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6314        }
6315        proc.uidRecord = uidRec;
6316
6317        // Reset render thread tid if it was already set, so new process can set it again.
6318        proc.renderThreadTid = 0;
6319        uidRec.numProcs++;
6320        mProcessNames.put(proc.processName, proc.uid, proc);
6321        if (proc.isolated) {
6322            mIsolatedProcesses.put(proc.uid, proc);
6323        }
6324    }
6325
6326    boolean removeProcessLocked(ProcessRecord app,
6327            boolean callerWillRestart, boolean allowRestart, String reason) {
6328        final String name = app.processName;
6329        final int uid = app.uid;
6330        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6331            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6332
6333        ProcessRecord old = mProcessNames.get(name, uid);
6334        if (old != app) {
6335            // This process is no longer active, so nothing to do.
6336            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6337            return false;
6338        }
6339        removeProcessNameLocked(name, uid);
6340        if (mHeavyWeightProcess == app) {
6341            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6342                    mHeavyWeightProcess.userId, 0));
6343            mHeavyWeightProcess = null;
6344        }
6345        boolean needRestart = false;
6346        if (app.pid > 0 && app.pid != MY_PID) {
6347            int pid = app.pid;
6348            synchronized (mPidsSelfLocked) {
6349                mPidsSelfLocked.remove(pid);
6350                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6351            }
6352            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6353            if (app.isolated) {
6354                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6355            }
6356            boolean willRestart = false;
6357            if (app.persistent && !app.isolated) {
6358                if (!callerWillRestart) {
6359                    willRestart = true;
6360                } else {
6361                    needRestart = true;
6362                }
6363            }
6364            app.kill(reason, true);
6365            handleAppDiedLocked(app, willRestart, allowRestart);
6366            if (willRestart) {
6367                removeLruProcessLocked(app);
6368                addAppLocked(app.info, false, null /* ABI override */);
6369            }
6370        } else {
6371            mRemovedProcesses.add(app);
6372        }
6373
6374        return needRestart;
6375    }
6376
6377    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6378        cleanupAppInLaunchingProvidersLocked(app, true);
6379        removeProcessLocked(app, false, true, "timeout publishing content providers");
6380    }
6381
6382    private final void processStartTimedOutLocked(ProcessRecord app) {
6383        final int pid = app.pid;
6384        boolean gone = false;
6385        synchronized (mPidsSelfLocked) {
6386            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6387            if (knownApp != null && knownApp.thread == null) {
6388                mPidsSelfLocked.remove(pid);
6389                gone = true;
6390            }
6391        }
6392
6393        if (gone) {
6394            Slog.w(TAG, "Process " + app + " failed to attach");
6395            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6396                    pid, app.uid, app.processName);
6397            removeProcessNameLocked(app.processName, app.uid);
6398            if (mHeavyWeightProcess == app) {
6399                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6400                        mHeavyWeightProcess.userId, 0));
6401                mHeavyWeightProcess = null;
6402            }
6403            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6404            if (app.isolated) {
6405                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6406            }
6407            // Take care of any launching providers waiting for this process.
6408            cleanupAppInLaunchingProvidersLocked(app, true);
6409            // Take care of any services that are waiting for the process.
6410            mServices.processStartTimedOutLocked(app);
6411            app.kill("start timeout", true);
6412            removeLruProcessLocked(app);
6413            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6414                Slog.w(TAG, "Unattached app died before backup, skipping");
6415                try {
6416                    IBackupManager bm = IBackupManager.Stub.asInterface(
6417                            ServiceManager.getService(Context.BACKUP_SERVICE));
6418                    bm.agentDisconnected(app.info.packageName);
6419                } catch (RemoteException e) {
6420                    // Can't happen; the backup manager is local
6421                }
6422            }
6423            if (isPendingBroadcastProcessLocked(pid)) {
6424                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6425                skipPendingBroadcastLocked(pid);
6426            }
6427        } else {
6428            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6429        }
6430    }
6431
6432    private final boolean attachApplicationLocked(IApplicationThread thread,
6433            int pid) {
6434
6435        // Find the application record that is being attached...  either via
6436        // the pid if we are running in multiple processes, or just pull the
6437        // next app record if we are emulating process with anonymous threads.
6438        ProcessRecord app;
6439        if (pid != MY_PID && pid >= 0) {
6440            synchronized (mPidsSelfLocked) {
6441                app = mPidsSelfLocked.get(pid);
6442            }
6443        } else {
6444            app = null;
6445        }
6446
6447        if (app == null) {
6448            Slog.w(TAG, "No pending application record for pid " + pid
6449                    + " (IApplicationThread " + thread + "); dropping process");
6450            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6451            if (pid > 0 && pid != MY_PID) {
6452                Process.killProcessQuiet(pid);
6453                //TODO: killProcessGroup(app.info.uid, pid);
6454            } else {
6455                try {
6456                    thread.scheduleExit();
6457                } catch (Exception e) {
6458                    // Ignore exceptions.
6459                }
6460            }
6461            return false;
6462        }
6463
6464        // If this application record is still attached to a previous
6465        // process, clean it up now.
6466        if (app.thread != null) {
6467            handleAppDiedLocked(app, true, true);
6468        }
6469
6470        // Tell the process all about itself.
6471
6472        if (DEBUG_ALL) Slog.v(
6473                TAG, "Binding process pid " + pid + " to record " + app);
6474
6475        final String processName = app.processName;
6476        try {
6477            AppDeathRecipient adr = new AppDeathRecipient(
6478                    app, pid, thread);
6479            thread.asBinder().linkToDeath(adr, 0);
6480            app.deathRecipient = adr;
6481        } catch (RemoteException e) {
6482            app.resetPackageList(mProcessStats);
6483            startProcessLocked(app, "link fail", processName);
6484            return false;
6485        }
6486
6487        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6488
6489        app.makeActive(thread, mProcessStats);
6490        app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6491        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6492        app.forcingToForeground = null;
6493        updateProcessForegroundLocked(app, false, false);
6494        app.hasShownUi = false;
6495        app.debugging = false;
6496        app.cached = false;
6497        app.killedByAm = false;
6498
6499        // We carefully use the same state that PackageManager uses for
6500        // filtering, since we use this flag to decide if we need to install
6501        // providers when user is unlocked later
6502        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6503
6504        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6505
6506        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6507        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6508
6509        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6510            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6511            msg.obj = app;
6512            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6513        }
6514
6515        if (!normalMode) {
6516            Slog.i(TAG, "Launching preboot mode app: " + app);
6517        }
6518
6519        if (DEBUG_ALL) Slog.v(
6520            TAG, "New app record " + app
6521            + " thread=" + thread.asBinder() + " pid=" + pid);
6522        try {
6523            int testMode = IApplicationThread.DEBUG_OFF;
6524            if (mDebugApp != null && mDebugApp.equals(processName)) {
6525                testMode = mWaitForDebugger
6526                    ? IApplicationThread.DEBUG_WAIT
6527                    : IApplicationThread.DEBUG_ON;
6528                app.debugging = true;
6529                if (mDebugTransient) {
6530                    mDebugApp = mOrigDebugApp;
6531                    mWaitForDebugger = mOrigWaitForDebugger;
6532                }
6533            }
6534            String profileFile = app.instrumentationProfileFile;
6535            ParcelFileDescriptor profileFd = null;
6536            int samplingInterval = 0;
6537            boolean profileAutoStop = false;
6538            if (mProfileApp != null && mProfileApp.equals(processName)) {
6539                mProfileProc = app;
6540                profileFile = mProfileFile;
6541                profileFd = mProfileFd;
6542                samplingInterval = mSamplingInterval;
6543                profileAutoStop = mAutoStopProfiler;
6544            }
6545            boolean enableTrackAllocation = false;
6546            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6547                enableTrackAllocation = true;
6548                mTrackAllocationApp = null;
6549            }
6550
6551            // If the app is being launched for restore or full backup, set it up specially
6552            boolean isRestrictedBackupMode = false;
6553            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6554                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6555                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6556                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6557                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6558            }
6559
6560            if (app.instrumentationClass != null) {
6561                notifyPackageUse(app.instrumentationClass.getPackageName(),
6562                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6563            }
6564            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6565                    + processName + " with config " + mConfiguration);
6566            ApplicationInfo appInfo = app.instrumentationInfo != null
6567                    ? app.instrumentationInfo : app.info;
6568            app.compat = compatibilityInfoForPackageLocked(appInfo);
6569            if (profileFd != null) {
6570                profileFd = profileFd.dup();
6571            }
6572            ProfilerInfo profilerInfo = profileFile == null ? null
6573                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6574            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6575                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6576                    app.instrumentationUiAutomationConnection, testMode,
6577                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6578                    isRestrictedBackupMode || !normalMode, app.persistent,
6579                    new Configuration(mConfiguration), app.compat,
6580                    getCommonServicesLocked(app.isolated),
6581                    mCoreSettingsObserver.getCoreSettingsLocked());
6582            updateLruProcessLocked(app, false, null);
6583            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6584        } catch (Exception e) {
6585            // todo: Yikes!  What should we do?  For now we will try to
6586            // start another process, but that could easily get us in
6587            // an infinite loop of restarting processes...
6588            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6589
6590            app.resetPackageList(mProcessStats);
6591            app.unlinkDeathRecipient();
6592            startProcessLocked(app, "bind fail", processName);
6593            return false;
6594        }
6595
6596        // Remove this record from the list of starting applications.
6597        mPersistentStartingProcesses.remove(app);
6598        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6599                "Attach application locked removing on hold: " + app);
6600        mProcessesOnHold.remove(app);
6601
6602        boolean badApp = false;
6603        boolean didSomething = false;
6604
6605        // See if the top visible activity is waiting to run in this process...
6606        if (normalMode) {
6607            try {
6608                if (mStackSupervisor.attachApplicationLocked(app)) {
6609                    didSomething = true;
6610                }
6611            } catch (Exception e) {
6612                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6613                badApp = true;
6614            }
6615        }
6616
6617        // Find any services that should be running in this process...
6618        if (!badApp) {
6619            try {
6620                didSomething |= mServices.attachApplicationLocked(app, processName);
6621            } catch (Exception e) {
6622                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6623                badApp = true;
6624            }
6625        }
6626
6627        // Check if a next-broadcast receiver is in this process...
6628        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6629            try {
6630                didSomething |= sendPendingBroadcastsLocked(app);
6631            } catch (Exception e) {
6632                // If the app died trying to launch the receiver we declare it 'bad'
6633                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6634                badApp = true;
6635            }
6636        }
6637
6638        // Check whether the next backup agent is in this process...
6639        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6640            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6641                    "New app is backup target, launching agent for " + app);
6642            notifyPackageUse(mBackupTarget.appInfo.packageName,
6643                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6644            try {
6645                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6646                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6647                        mBackupTarget.backupMode);
6648            } catch (Exception e) {
6649                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6650                badApp = true;
6651            }
6652        }
6653
6654        if (badApp) {
6655            app.kill("error during init", true);
6656            handleAppDiedLocked(app, false, true);
6657            return false;
6658        }
6659
6660        if (!didSomething) {
6661            updateOomAdjLocked();
6662        }
6663
6664        return true;
6665    }
6666
6667    @Override
6668    public final void attachApplication(IApplicationThread thread) {
6669        synchronized (this) {
6670            int callingPid = Binder.getCallingPid();
6671            final long origId = Binder.clearCallingIdentity();
6672            attachApplicationLocked(thread, callingPid);
6673            Binder.restoreCallingIdentity(origId);
6674        }
6675    }
6676
6677    @Override
6678    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6679        final long origId = Binder.clearCallingIdentity();
6680        synchronized (this) {
6681            ActivityStack stack = ActivityRecord.getStackLocked(token);
6682            if (stack != null) {
6683                ActivityRecord r =
6684                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6685                if (stopProfiling) {
6686                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6687                        try {
6688                            mProfileFd.close();
6689                        } catch (IOException e) {
6690                        }
6691                        clearProfilerLocked();
6692                    }
6693                }
6694            }
6695        }
6696        Binder.restoreCallingIdentity(origId);
6697    }
6698
6699    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6700        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6701                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6702    }
6703
6704    void enableScreenAfterBoot() {
6705        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6706                SystemClock.uptimeMillis());
6707        mWindowManager.enableScreenAfterBoot();
6708
6709        synchronized (this) {
6710            updateEventDispatchingLocked();
6711        }
6712    }
6713
6714    @Override
6715    public void showBootMessage(final CharSequence msg, final boolean always) {
6716        if (Binder.getCallingUid() != Process.myUid()) {
6717            throw new SecurityException();
6718        }
6719        mWindowManager.showBootMessage(msg, always);
6720    }
6721
6722    @Override
6723    public void keyguardWaitingForActivityDrawn() {
6724        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6725        final long token = Binder.clearCallingIdentity();
6726        try {
6727            synchronized (this) {
6728                if (DEBUG_LOCKSCREEN) logLockScreen("");
6729                mWindowManager.keyguardWaitingForActivityDrawn();
6730                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6731                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6732                    updateSleepIfNeededLocked();
6733                }
6734            }
6735        } finally {
6736            Binder.restoreCallingIdentity(token);
6737        }
6738    }
6739
6740    @Override
6741    public void keyguardGoingAway(int flags) {
6742        enforceNotIsolatedCaller("keyguardGoingAway");
6743        final long token = Binder.clearCallingIdentity();
6744        try {
6745            synchronized (this) {
6746                if (DEBUG_LOCKSCREEN) logLockScreen("");
6747                mWindowManager.keyguardGoingAway(flags);
6748                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6749                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6750                    updateSleepIfNeededLocked();
6751
6752                    // Some stack visibility might change (e.g. docked stack)
6753                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6754                    applyVrModeIfNeededLocked(mFocusedActivity, true);
6755                }
6756            }
6757        } finally {
6758            Binder.restoreCallingIdentity(token);
6759        }
6760    }
6761
6762    final void finishBooting() {
6763        synchronized (this) {
6764            if (!mBootAnimationComplete) {
6765                mCallFinishBooting = true;
6766                return;
6767            }
6768            mCallFinishBooting = false;
6769        }
6770
6771        ArraySet<String> completedIsas = new ArraySet<String>();
6772        for (String abi : Build.SUPPORTED_ABIS) {
6773            Process.establishZygoteConnectionForAbi(abi);
6774            final String instructionSet = VMRuntime.getInstructionSet(abi);
6775            if (!completedIsas.contains(instructionSet)) {
6776                try {
6777                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6778                } catch (InstallerException e) {
6779                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6780                            e.getMessage() +")");
6781                }
6782                completedIsas.add(instructionSet);
6783            }
6784        }
6785
6786        IntentFilter pkgFilter = new IntentFilter();
6787        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6788        pkgFilter.addDataScheme("package");
6789        mContext.registerReceiver(new BroadcastReceiver() {
6790            @Override
6791            public void onReceive(Context context, Intent intent) {
6792                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6793                if (pkgs != null) {
6794                    for (String pkg : pkgs) {
6795                        synchronized (ActivityManagerService.this) {
6796                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6797                                    0, "query restart")) {
6798                                setResultCode(Activity.RESULT_OK);
6799                                return;
6800                            }
6801                        }
6802                    }
6803                }
6804            }
6805        }, pkgFilter);
6806
6807        IntentFilter dumpheapFilter = new IntentFilter();
6808        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6809        mContext.registerReceiver(new BroadcastReceiver() {
6810            @Override
6811            public void onReceive(Context context, Intent intent) {
6812                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6813                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6814                } else {
6815                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6816                }
6817            }
6818        }, dumpheapFilter);
6819
6820        // Let system services know.
6821        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6822
6823        synchronized (this) {
6824            // Ensure that any processes we had put on hold are now started
6825            // up.
6826            final int NP = mProcessesOnHold.size();
6827            if (NP > 0) {
6828                ArrayList<ProcessRecord> procs =
6829                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6830                for (int ip=0; ip<NP; ip++) {
6831                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6832                            + procs.get(ip));
6833                    startProcessLocked(procs.get(ip), "on-hold", null);
6834                }
6835            }
6836
6837            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6838                // Start looking for apps that are abusing wake locks.
6839                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6840                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6841                // Tell anyone interested that we are done booting!
6842                SystemProperties.set("sys.boot_completed", "1");
6843
6844                // And trigger dev.bootcomplete if we are not showing encryption progress
6845                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6846                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6847                    SystemProperties.set("dev.bootcomplete", "1");
6848                }
6849                mUserController.sendBootCompletedLocked(
6850                        new IIntentReceiver.Stub() {
6851                            @Override
6852                            public void performReceive(Intent intent, int resultCode,
6853                                    String data, Bundle extras, boolean ordered,
6854                                    boolean sticky, int sendingUser) {
6855                                synchronized (ActivityManagerService.this) {
6856                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6857                                            true, false);
6858                                }
6859                            }
6860                        });
6861                scheduleStartProfilesLocked();
6862            }
6863        }
6864    }
6865
6866    @Override
6867    public void bootAnimationComplete() {
6868        final boolean callFinishBooting;
6869        synchronized (this) {
6870            callFinishBooting = mCallFinishBooting;
6871            mBootAnimationComplete = true;
6872        }
6873        if (callFinishBooting) {
6874            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6875            finishBooting();
6876            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6877        }
6878    }
6879
6880    final void ensureBootCompleted() {
6881        boolean booting;
6882        boolean enableScreen;
6883        synchronized (this) {
6884            booting = mBooting;
6885            mBooting = false;
6886            enableScreen = !mBooted;
6887            mBooted = true;
6888        }
6889
6890        if (booting) {
6891            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6892            finishBooting();
6893            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6894        }
6895
6896        if (enableScreen) {
6897            enableScreenAfterBoot();
6898        }
6899    }
6900
6901    @Override
6902    public final void activityResumed(IBinder token) {
6903        final long origId = Binder.clearCallingIdentity();
6904        synchronized(this) {
6905            ActivityStack stack = ActivityRecord.getStackLocked(token);
6906            if (stack != null) {
6907                stack.activityResumedLocked(token);
6908            }
6909        }
6910        Binder.restoreCallingIdentity(origId);
6911    }
6912
6913    @Override
6914    public final void activityPaused(IBinder token) {
6915        final long origId = Binder.clearCallingIdentity();
6916        synchronized(this) {
6917            ActivityStack stack = ActivityRecord.getStackLocked(token);
6918            if (stack != null) {
6919                stack.activityPausedLocked(token, false);
6920            }
6921        }
6922        Binder.restoreCallingIdentity(origId);
6923    }
6924
6925    @Override
6926    public final void activityStopped(IBinder token, Bundle icicle,
6927            PersistableBundle persistentState, CharSequence description) {
6928        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6929
6930        // Refuse possible leaked file descriptors
6931        if (icicle != null && icicle.hasFileDescriptors()) {
6932            throw new IllegalArgumentException("File descriptors passed in Bundle");
6933        }
6934
6935        final long origId = Binder.clearCallingIdentity();
6936
6937        synchronized (this) {
6938            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6939            if (r != null) {
6940                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6941            }
6942        }
6943
6944        trimApplications();
6945
6946        Binder.restoreCallingIdentity(origId);
6947    }
6948
6949    @Override
6950    public final void activityDestroyed(IBinder token) {
6951        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6952        synchronized (this) {
6953            ActivityStack stack = ActivityRecord.getStackLocked(token);
6954            if (stack != null) {
6955                stack.activityDestroyedLocked(token, "activityDestroyed");
6956            }
6957        }
6958    }
6959
6960    @Override
6961    public final void activityRelaunched(IBinder token) {
6962        final long origId = Binder.clearCallingIdentity();
6963        synchronized (this) {
6964            mStackSupervisor.activityRelaunchedLocked(token);
6965        }
6966        Binder.restoreCallingIdentity(origId);
6967    }
6968
6969    @Override
6970    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6971            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6972        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6973                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6974        synchronized (this) {
6975            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6976            if (record == null) {
6977                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6978                        + "found for: " + token);
6979            }
6980            record.setSizeConfigurations(horizontalSizeConfiguration,
6981                    verticalSizeConfigurations, smallestSizeConfigurations);
6982        }
6983    }
6984
6985    @Override
6986    public final void backgroundResourcesReleased(IBinder token) {
6987        final long origId = Binder.clearCallingIdentity();
6988        try {
6989            synchronized (this) {
6990                ActivityStack stack = ActivityRecord.getStackLocked(token);
6991                if (stack != null) {
6992                    stack.backgroundResourcesReleased();
6993                }
6994            }
6995        } finally {
6996            Binder.restoreCallingIdentity(origId);
6997        }
6998    }
6999
7000    @Override
7001    public final void notifyLaunchTaskBehindComplete(IBinder token) {
7002        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
7003    }
7004
7005    @Override
7006    public final void notifyEnterAnimationComplete(IBinder token) {
7007        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
7008    }
7009
7010    @Override
7011    public String getCallingPackage(IBinder token) {
7012        synchronized (this) {
7013            ActivityRecord r = getCallingRecordLocked(token);
7014            return r != null ? r.info.packageName : null;
7015        }
7016    }
7017
7018    @Override
7019    public ComponentName getCallingActivity(IBinder token) {
7020        synchronized (this) {
7021            ActivityRecord r = getCallingRecordLocked(token);
7022            return r != null ? r.intent.getComponent() : null;
7023        }
7024    }
7025
7026    private ActivityRecord getCallingRecordLocked(IBinder token) {
7027        ActivityRecord r = ActivityRecord.isInStackLocked(token);
7028        if (r == null) {
7029            return null;
7030        }
7031        return r.resultTo;
7032    }
7033
7034    @Override
7035    public ComponentName getActivityClassForToken(IBinder token) {
7036        synchronized(this) {
7037            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7038            if (r == null) {
7039                return null;
7040            }
7041            return r.intent.getComponent();
7042        }
7043    }
7044
7045    @Override
7046    public String getPackageForToken(IBinder token) {
7047        synchronized(this) {
7048            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7049            if (r == null) {
7050                return null;
7051            }
7052            return r.packageName;
7053        }
7054    }
7055
7056    @Override
7057    public boolean isRootVoiceInteraction(IBinder token) {
7058        synchronized(this) {
7059            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7060            if (r == null) {
7061                return false;
7062            }
7063            return r.rootVoiceInteraction;
7064        }
7065    }
7066
7067    @Override
7068    public IIntentSender getIntentSender(int type,
7069            String packageName, IBinder token, String resultWho,
7070            int requestCode, Intent[] intents, String[] resolvedTypes,
7071            int flags, Bundle bOptions, int userId) {
7072        enforceNotIsolatedCaller("getIntentSender");
7073        // Refuse possible leaked file descriptors
7074        if (intents != null) {
7075            if (intents.length < 1) {
7076                throw new IllegalArgumentException("Intents array length must be >= 1");
7077            }
7078            for (int i=0; i<intents.length; i++) {
7079                Intent intent = intents[i];
7080                if (intent != null) {
7081                    if (intent.hasFileDescriptors()) {
7082                        throw new IllegalArgumentException("File descriptors passed in Intent");
7083                    }
7084                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7085                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7086                        throw new IllegalArgumentException(
7087                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7088                    }
7089                    intents[i] = new Intent(intent);
7090                }
7091            }
7092            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7093                throw new IllegalArgumentException(
7094                        "Intent array length does not match resolvedTypes length");
7095            }
7096        }
7097        if (bOptions != null) {
7098            if (bOptions.hasFileDescriptors()) {
7099                throw new IllegalArgumentException("File descriptors passed in options");
7100            }
7101        }
7102
7103        synchronized(this) {
7104            int callingUid = Binder.getCallingUid();
7105            int origUserId = userId;
7106            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7107                    type == ActivityManager.INTENT_SENDER_BROADCAST,
7108                    ALLOW_NON_FULL, "getIntentSender", null);
7109            if (origUserId == UserHandle.USER_CURRENT) {
7110                // We don't want to evaluate this until the pending intent is
7111                // actually executed.  However, we do want to always do the
7112                // security checking for it above.
7113                userId = UserHandle.USER_CURRENT;
7114            }
7115            try {
7116                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
7117                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7118                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7119                    if (!UserHandle.isSameApp(callingUid, uid)) {
7120                        String msg = "Permission Denial: getIntentSender() from pid="
7121                            + Binder.getCallingPid()
7122                            + ", uid=" + Binder.getCallingUid()
7123                            + ", (need uid=" + uid + ")"
7124                            + " is not allowed to send as package " + packageName;
7125                        Slog.w(TAG, msg);
7126                        throw new SecurityException(msg);
7127                    }
7128                }
7129
7130                return getIntentSenderLocked(type, packageName, callingUid, userId,
7131                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7132
7133            } catch (RemoteException e) {
7134                throw new SecurityException(e);
7135            }
7136        }
7137    }
7138
7139    IIntentSender getIntentSenderLocked(int type, String packageName,
7140            int callingUid, int userId, IBinder token, String resultWho,
7141            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7142            Bundle bOptions) {
7143        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7144        ActivityRecord activity = null;
7145        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7146            activity = ActivityRecord.isInStackLocked(token);
7147            if (activity == null) {
7148                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7149                return null;
7150            }
7151            if (activity.finishing) {
7152                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7153                return null;
7154            }
7155        }
7156
7157        // We're going to be splicing together extras before sending, so we're
7158        // okay poking into any contained extras.
7159        if (intents != null) {
7160            for (int i = 0; i < intents.length; i++) {
7161                intents[i].setDefusable(true);
7162            }
7163        }
7164        Bundle.setDefusable(bOptions, true);
7165
7166        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7167        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7168        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7169        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7170                |PendingIntent.FLAG_UPDATE_CURRENT);
7171
7172        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7173                type, packageName, activity, resultWho,
7174                requestCode, intents, resolvedTypes, flags, bOptions, userId);
7175        WeakReference<PendingIntentRecord> ref;
7176        ref = mIntentSenderRecords.get(key);
7177        PendingIntentRecord rec = ref != null ? ref.get() : null;
7178        if (rec != null) {
7179            if (!cancelCurrent) {
7180                if (updateCurrent) {
7181                    if (rec.key.requestIntent != null) {
7182                        rec.key.requestIntent.replaceExtras(intents != null ?
7183                                intents[intents.length - 1] : null);
7184                    }
7185                    if (intents != null) {
7186                        intents[intents.length-1] = rec.key.requestIntent;
7187                        rec.key.allIntents = intents;
7188                        rec.key.allResolvedTypes = resolvedTypes;
7189                    } else {
7190                        rec.key.allIntents = null;
7191                        rec.key.allResolvedTypes = null;
7192                    }
7193                }
7194                return rec;
7195            }
7196            rec.canceled = true;
7197            mIntentSenderRecords.remove(key);
7198        }
7199        if (noCreate) {
7200            return rec;
7201        }
7202        rec = new PendingIntentRecord(this, key, callingUid);
7203        mIntentSenderRecords.put(key, rec.ref);
7204        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7205            if (activity.pendingResults == null) {
7206                activity.pendingResults
7207                        = new HashSet<WeakReference<PendingIntentRecord>>();
7208            }
7209            activity.pendingResults.add(rec.ref);
7210        }
7211        return rec;
7212    }
7213
7214    @Override
7215    public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7216            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7217        if (target instanceof PendingIntentRecord) {
7218            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7219                    finishedReceiver, requiredPermission, options);
7220        } else {
7221            if (intent == null) {
7222                // Weird case: someone has given us their own custom IIntentSender, and now
7223                // they have someone else trying to send to it but of course this isn't
7224                // really a PendingIntent, so there is no base Intent, and the caller isn't
7225                // supplying an Intent... but we never want to dispatch a null Intent to
7226                // a receiver, so um...  let's make something up.
7227                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7228                intent = new Intent(Intent.ACTION_MAIN);
7229            }
7230            try {
7231                target.send(code, intent, resolvedType, null, requiredPermission, options);
7232            } catch (RemoteException e) {
7233            }
7234            // Platform code can rely on getting a result back when the send is done, but if
7235            // this intent sender is from outside of the system we can't rely on it doing that.
7236            // So instead we don't give it the result receiver, and instead just directly
7237            // report the finish immediately.
7238            if (finishedReceiver != null) {
7239                try {
7240                    finishedReceiver.performReceive(intent, 0,
7241                            null, null, false, false, UserHandle.getCallingUserId());
7242                } catch (RemoteException e) {
7243                }
7244            }
7245            return 0;
7246        }
7247    }
7248
7249    /**
7250     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
7251     *
7252     * <p>{@code callerUid} must be allowed to request such whitelist by calling
7253     * {@link #addTempPowerSaveWhitelistGrantorUid(int)}.
7254     */
7255    void tempWhitelistAppForPowerSave(int callerPid, int callerUid, int targetUid, long duration) {
7256        if (DEBUG_WHITELISTS) {
7257            Slog.d(TAG, "tempWhitelistAppForPowerSave(" + callerPid + ", " + callerUid + ", "
7258                    + targetUid + ", " + duration + ")");
7259        }
7260        synchronized (mPidsSelfLocked) {
7261            final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
7262            if (pr == null) {
7263                Slog.w(TAG, "tempWhitelistAppForPowerSave() no ProcessRecord for pid " + callerPid);
7264                return;
7265            }
7266            if (!pr.whitelistManager) {
7267                if (DEBUG_WHITELISTS) {
7268                    Slog.d(TAG, "tempWhitelistAppForPowerSave() for target " + targetUid + ": pid "
7269                            + callerPid + " is not allowed");
7270                }
7271                return;
7272            }
7273        }
7274
7275        final long token = Binder.clearCallingIdentity();
7276        try {
7277            mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(targetUid, duration,
7278                    true, "pe from uid:" + callerUid);
7279        } finally {
7280            Binder.restoreCallingIdentity(token);
7281        }
7282    }
7283
7284    @Override
7285    public void cancelIntentSender(IIntentSender sender) {
7286        if (!(sender instanceof PendingIntentRecord)) {
7287            return;
7288        }
7289        synchronized(this) {
7290            PendingIntentRecord rec = (PendingIntentRecord)sender;
7291            try {
7292                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7293                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7294                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7295                    String msg = "Permission Denial: cancelIntentSender() from pid="
7296                        + Binder.getCallingPid()
7297                        + ", uid=" + Binder.getCallingUid()
7298                        + " is not allowed to cancel packges "
7299                        + rec.key.packageName;
7300                    Slog.w(TAG, msg);
7301                    throw new SecurityException(msg);
7302                }
7303            } catch (RemoteException e) {
7304                throw new SecurityException(e);
7305            }
7306            cancelIntentSenderLocked(rec, true);
7307        }
7308    }
7309
7310    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7311        rec.canceled = true;
7312        mIntentSenderRecords.remove(rec.key);
7313        if (cleanActivity && rec.key.activity != null) {
7314            rec.key.activity.pendingResults.remove(rec.ref);
7315        }
7316    }
7317
7318    @Override
7319    public String getPackageForIntentSender(IIntentSender pendingResult) {
7320        if (!(pendingResult instanceof PendingIntentRecord)) {
7321            return null;
7322        }
7323        try {
7324            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7325            return res.key.packageName;
7326        } catch (ClassCastException e) {
7327        }
7328        return null;
7329    }
7330
7331    @Override
7332    public int getUidForIntentSender(IIntentSender sender) {
7333        if (sender instanceof PendingIntentRecord) {
7334            try {
7335                PendingIntentRecord res = (PendingIntentRecord)sender;
7336                return res.uid;
7337            } catch (ClassCastException e) {
7338            }
7339        }
7340        return -1;
7341    }
7342
7343    @Override
7344    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7345        if (!(pendingResult instanceof PendingIntentRecord)) {
7346            return false;
7347        }
7348        try {
7349            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7350            if (res.key.allIntents == null) {
7351                return false;
7352            }
7353            for (int i=0; i<res.key.allIntents.length; i++) {
7354                Intent intent = res.key.allIntents[i];
7355                if (intent.getPackage() != null && intent.getComponent() != null) {
7356                    return false;
7357                }
7358            }
7359            return true;
7360        } catch (ClassCastException e) {
7361        }
7362        return false;
7363    }
7364
7365    @Override
7366    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7367        if (!(pendingResult instanceof PendingIntentRecord)) {
7368            return false;
7369        }
7370        try {
7371            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7372            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7373                return true;
7374            }
7375            return false;
7376        } catch (ClassCastException e) {
7377        }
7378        return false;
7379    }
7380
7381    @Override
7382    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7383        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7384                "getIntentForIntentSender()");
7385        if (!(pendingResult instanceof PendingIntentRecord)) {
7386            return null;
7387        }
7388        try {
7389            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7390            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7391        } catch (ClassCastException e) {
7392        }
7393        return null;
7394    }
7395
7396    @Override
7397    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7398        if (!(pendingResult instanceof PendingIntentRecord)) {
7399            return null;
7400        }
7401        try {
7402            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7403            synchronized (this) {
7404                return getTagForIntentSenderLocked(res, prefix);
7405            }
7406        } catch (ClassCastException e) {
7407        }
7408        return null;
7409    }
7410
7411    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7412        final Intent intent = res.key.requestIntent;
7413        if (intent != null) {
7414            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7415                    || res.lastTagPrefix.equals(prefix))) {
7416                return res.lastTag;
7417            }
7418            res.lastTagPrefix = prefix;
7419            final StringBuilder sb = new StringBuilder(128);
7420            if (prefix != null) {
7421                sb.append(prefix);
7422            }
7423            if (intent.getAction() != null) {
7424                sb.append(intent.getAction());
7425            } else if (intent.getComponent() != null) {
7426                intent.getComponent().appendShortString(sb);
7427            } else {
7428                sb.append("?");
7429            }
7430            return res.lastTag = sb.toString();
7431        }
7432        return null;
7433    }
7434
7435    @Override
7436    public void setProcessLimit(int max) {
7437        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7438                "setProcessLimit()");
7439        synchronized (this) {
7440            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7441            mProcessLimitOverride = max;
7442        }
7443        trimApplications();
7444    }
7445
7446    @Override
7447    public int getProcessLimit() {
7448        synchronized (this) {
7449            return mProcessLimitOverride;
7450        }
7451    }
7452
7453    void foregroundTokenDied(ForegroundToken token) {
7454        synchronized (ActivityManagerService.this) {
7455            synchronized (mPidsSelfLocked) {
7456                ForegroundToken cur
7457                    = mForegroundProcesses.get(token.pid);
7458                if (cur != token) {
7459                    return;
7460                }
7461                mForegroundProcesses.remove(token.pid);
7462                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7463                if (pr == null) {
7464                    return;
7465                }
7466                pr.forcingToForeground = null;
7467                updateProcessForegroundLocked(pr, false, false);
7468            }
7469            updateOomAdjLocked();
7470        }
7471    }
7472
7473    @Override
7474    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7475        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7476                "setProcessForeground()");
7477        synchronized(this) {
7478            boolean changed = false;
7479
7480            synchronized (mPidsSelfLocked) {
7481                ProcessRecord pr = mPidsSelfLocked.get(pid);
7482                if (pr == null && isForeground) {
7483                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7484                    return;
7485                }
7486                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7487                if (oldToken != null) {
7488                    oldToken.token.unlinkToDeath(oldToken, 0);
7489                    mForegroundProcesses.remove(pid);
7490                    if (pr != null) {
7491                        pr.forcingToForeground = null;
7492                    }
7493                    changed = true;
7494                }
7495                if (isForeground && token != null) {
7496                    ForegroundToken newToken = new ForegroundToken() {
7497                        @Override
7498                        public void binderDied() {
7499                            foregroundTokenDied(this);
7500                        }
7501                    };
7502                    newToken.pid = pid;
7503                    newToken.token = token;
7504                    try {
7505                        token.linkToDeath(newToken, 0);
7506                        mForegroundProcesses.put(pid, newToken);
7507                        pr.forcingToForeground = token;
7508                        changed = true;
7509                    } catch (RemoteException e) {
7510                        // If the process died while doing this, we will later
7511                        // do the cleanup with the process death link.
7512                    }
7513                }
7514            }
7515
7516            if (changed) {
7517                updateOomAdjLocked();
7518            }
7519        }
7520    }
7521
7522    @Override
7523    public boolean isAppForeground(int uid) throws RemoteException {
7524        synchronized (this) {
7525            UidRecord uidRec = mActiveUids.get(uid);
7526            if (uidRec == null || uidRec.idle) {
7527                return false;
7528            }
7529            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7530        }
7531    }
7532
7533    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7534    // be guarded by permission checking.
7535    int getUidState(int uid) {
7536        synchronized (this) {
7537            UidRecord uidRec = mActiveUids.get(uid);
7538            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7539        }
7540    }
7541
7542    @Override
7543    public boolean isInMultiWindowMode(IBinder token) {
7544        final long origId = Binder.clearCallingIdentity();
7545        try {
7546            synchronized(this) {
7547                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7548                if (r == null) {
7549                    return false;
7550                }
7551                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7552                return !r.task.mFullscreen;
7553            }
7554        } finally {
7555            Binder.restoreCallingIdentity(origId);
7556        }
7557    }
7558
7559    @Override
7560    public boolean isInPictureInPictureMode(IBinder token) {
7561        final long origId = Binder.clearCallingIdentity();
7562        try {
7563            synchronized(this) {
7564                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7565                if (stack == null) {
7566                    return false;
7567                }
7568                return stack.mStackId == PINNED_STACK_ID;
7569            }
7570        } finally {
7571            Binder.restoreCallingIdentity(origId);
7572        }
7573    }
7574
7575    @Override
7576    public void enterPictureInPictureMode(IBinder token) {
7577        final long origId = Binder.clearCallingIdentity();
7578        try {
7579            synchronized(this) {
7580                if (!mSupportsPictureInPicture) {
7581                    throw new IllegalStateException("enterPictureInPictureMode: "
7582                            + "Device doesn't support picture-in-picture mode.");
7583                }
7584
7585                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7586
7587                if (r == null) {
7588                    throw new IllegalStateException("enterPictureInPictureMode: "
7589                            + "Can't find activity for token=" + token);
7590                }
7591
7592                if (!r.supportsPictureInPicture()) {
7593                    throw new IllegalArgumentException("enterPictureInPictureMode: "
7594                            + "Picture-In-Picture not supported for r=" + r);
7595                }
7596
7597                // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
7598                // current bounds.
7599                final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
7600                final Rect bounds = (pinnedStack != null)
7601                        ? pinnedStack.mBounds : mDefaultPinnedStackBounds;
7602
7603                mStackSupervisor.moveActivityToPinnedStackLocked(
7604                        r, "enterPictureInPictureMode", bounds);
7605            }
7606        } finally {
7607            Binder.restoreCallingIdentity(origId);
7608        }
7609    }
7610
7611    // =========================================================
7612    // PROCESS INFO
7613    // =========================================================
7614
7615    static class ProcessInfoService extends IProcessInfoService.Stub {
7616        final ActivityManagerService mActivityManagerService;
7617        ProcessInfoService(ActivityManagerService activityManagerService) {
7618            mActivityManagerService = activityManagerService;
7619        }
7620
7621        @Override
7622        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7623            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7624                    /*in*/ pids, /*out*/ states, null);
7625        }
7626
7627        @Override
7628        public void getProcessStatesAndOomScoresFromPids(
7629                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7630            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7631                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7632        }
7633    }
7634
7635    /**
7636     * For each PID in the given input array, write the current process state
7637     * for that process into the states array, or -1 to indicate that no
7638     * process with the given PID exists. If scores array is provided, write
7639     * the oom score for the process into the scores array, with INVALID_ADJ
7640     * indicating the PID doesn't exist.
7641     */
7642    public void getProcessStatesAndOomScoresForPIDs(
7643            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7644        if (scores != null) {
7645            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7646                    "getProcessStatesAndOomScoresForPIDs()");
7647        }
7648
7649        if (pids == null) {
7650            throw new NullPointerException("pids");
7651        } else if (states == null) {
7652            throw new NullPointerException("states");
7653        } else if (pids.length != states.length) {
7654            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7655        } else if (scores != null && pids.length != scores.length) {
7656            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7657        }
7658
7659        synchronized (mPidsSelfLocked) {
7660            for (int i = 0; i < pids.length; i++) {
7661                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7662                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7663                        pr.curProcState;
7664                if (scores != null) {
7665                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7666                }
7667            }
7668        }
7669    }
7670
7671    // =========================================================
7672    // PERMISSIONS
7673    // =========================================================
7674
7675    static class PermissionController extends IPermissionController.Stub {
7676        ActivityManagerService mActivityManagerService;
7677        PermissionController(ActivityManagerService activityManagerService) {
7678            mActivityManagerService = activityManagerService;
7679        }
7680
7681        @Override
7682        public boolean checkPermission(String permission, int pid, int uid) {
7683            return mActivityManagerService.checkPermission(permission, pid,
7684                    uid) == PackageManager.PERMISSION_GRANTED;
7685        }
7686
7687        @Override
7688        public String[] getPackagesForUid(int uid) {
7689            return mActivityManagerService.mContext.getPackageManager()
7690                    .getPackagesForUid(uid);
7691        }
7692
7693        @Override
7694        public boolean isRuntimePermission(String permission) {
7695            try {
7696                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7697                        .getPermissionInfo(permission, 0);
7698                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7699            } catch (NameNotFoundException nnfe) {
7700                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7701            }
7702            return false;
7703        }
7704    }
7705
7706    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7707        @Override
7708        public int checkComponentPermission(String permission, int pid, int uid,
7709                int owningUid, boolean exported) {
7710            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7711                    owningUid, exported);
7712        }
7713
7714        @Override
7715        public Object getAMSLock() {
7716            return ActivityManagerService.this;
7717        }
7718    }
7719
7720    /**
7721     * This can be called with or without the global lock held.
7722     */
7723    int checkComponentPermission(String permission, int pid, int uid,
7724            int owningUid, boolean exported) {
7725        if (pid == MY_PID) {
7726            return PackageManager.PERMISSION_GRANTED;
7727        }
7728        return ActivityManager.checkComponentPermission(permission, uid,
7729                owningUid, exported);
7730    }
7731
7732    /**
7733     * As the only public entry point for permissions checking, this method
7734     * can enforce the semantic that requesting a check on a null global
7735     * permission is automatically denied.  (Internally a null permission
7736     * string is used when calling {@link #checkComponentPermission} in cases
7737     * when only uid-based security is needed.)
7738     *
7739     * This can be called with or without the global lock held.
7740     */
7741    @Override
7742    public int checkPermission(String permission, int pid, int uid) {
7743        if (permission == null) {
7744            return PackageManager.PERMISSION_DENIED;
7745        }
7746        return checkComponentPermission(permission, pid, uid, -1, true);
7747    }
7748
7749    @Override
7750    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7751        if (permission == null) {
7752            return PackageManager.PERMISSION_DENIED;
7753        }
7754
7755        // We might be performing an operation on behalf of an indirect binder
7756        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7757        // client identity accordingly before proceeding.
7758        Identity tlsIdentity = sCallerIdentity.get();
7759        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7760            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7761                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7762            uid = tlsIdentity.uid;
7763            pid = tlsIdentity.pid;
7764        }
7765
7766        return checkComponentPermission(permission, pid, uid, -1, true);
7767    }
7768
7769    /**
7770     * Binder IPC calls go through the public entry point.
7771     * This can be called with or without the global lock held.
7772     */
7773    int checkCallingPermission(String permission) {
7774        return checkPermission(permission,
7775                Binder.getCallingPid(),
7776                UserHandle.getAppId(Binder.getCallingUid()));
7777    }
7778
7779    /**
7780     * This can be called with or without the global lock held.
7781     */
7782    void enforceCallingPermission(String permission, String func) {
7783        if (checkCallingPermission(permission)
7784                == PackageManager.PERMISSION_GRANTED) {
7785            return;
7786        }
7787
7788        String msg = "Permission Denial: " + func + " from pid="
7789                + Binder.getCallingPid()
7790                + ", uid=" + Binder.getCallingUid()
7791                + " requires " + permission;
7792        Slog.w(TAG, msg);
7793        throw new SecurityException(msg);
7794    }
7795
7796    /**
7797     * Determine if UID is holding permissions required to access {@link Uri} in
7798     * the given {@link ProviderInfo}. Final permission checking is always done
7799     * in {@link ContentProvider}.
7800     */
7801    private final boolean checkHoldingPermissionsLocked(
7802            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7803        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7804                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7805        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7806            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7807                    != PERMISSION_GRANTED) {
7808                return false;
7809            }
7810        }
7811        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7812    }
7813
7814    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7815            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7816        if (pi.applicationInfo.uid == uid) {
7817            return true;
7818        } else if (!pi.exported) {
7819            return false;
7820        }
7821
7822        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7823        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7824        try {
7825            // check if target holds top-level <provider> permissions
7826            if (!readMet && pi.readPermission != null && considerUidPermissions
7827                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7828                readMet = true;
7829            }
7830            if (!writeMet && pi.writePermission != null && considerUidPermissions
7831                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7832                writeMet = true;
7833            }
7834
7835            // track if unprotected read/write is allowed; any denied
7836            // <path-permission> below removes this ability
7837            boolean allowDefaultRead = pi.readPermission == null;
7838            boolean allowDefaultWrite = pi.writePermission == null;
7839
7840            // check if target holds any <path-permission> that match uri
7841            final PathPermission[] pps = pi.pathPermissions;
7842            if (pps != null) {
7843                final String path = grantUri.uri.getPath();
7844                int i = pps.length;
7845                while (i > 0 && (!readMet || !writeMet)) {
7846                    i--;
7847                    PathPermission pp = pps[i];
7848                    if (pp.match(path)) {
7849                        if (!readMet) {
7850                            final String pprperm = pp.getReadPermission();
7851                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7852                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7853                                    + ": match=" + pp.match(path)
7854                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7855                            if (pprperm != null) {
7856                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7857                                        == PERMISSION_GRANTED) {
7858                                    readMet = true;
7859                                } else {
7860                                    allowDefaultRead = false;
7861                                }
7862                            }
7863                        }
7864                        if (!writeMet) {
7865                            final String ppwperm = pp.getWritePermission();
7866                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7867                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7868                                    + ": match=" + pp.match(path)
7869                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7870                            if (ppwperm != null) {
7871                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7872                                        == PERMISSION_GRANTED) {
7873                                    writeMet = true;
7874                                } else {
7875                                    allowDefaultWrite = false;
7876                                }
7877                            }
7878                        }
7879                    }
7880                }
7881            }
7882
7883            // grant unprotected <provider> read/write, if not blocked by
7884            // <path-permission> above
7885            if (allowDefaultRead) readMet = true;
7886            if (allowDefaultWrite) writeMet = true;
7887
7888        } catch (RemoteException e) {
7889            return false;
7890        }
7891
7892        return readMet && writeMet;
7893    }
7894
7895    public int getAppStartMode(int uid, String packageName) {
7896        synchronized (this) {
7897            return checkAllowBackgroundLocked(uid, packageName, -1, true);
7898        }
7899    }
7900
7901    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7902            boolean allowWhenForeground) {
7903        UidRecord uidRec = mActiveUids.get(uid);
7904        if (!mLenientBackgroundCheck) {
7905            if (!allowWhenForeground || uidRec == null
7906                    || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7907                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7908                        packageName) != AppOpsManager.MODE_ALLOWED) {
7909                    return ActivityManager.APP_START_MODE_DELAYED;
7910                }
7911            }
7912
7913        } else if (uidRec == null || uidRec.idle) {
7914            if (callingPid >= 0) {
7915                ProcessRecord proc;
7916                synchronized (mPidsSelfLocked) {
7917                    proc = mPidsSelfLocked.get(callingPid);
7918                }
7919                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7920                    // Whoever is instigating this is in the foreground, so we will allow it
7921                    // to go through.
7922                    return ActivityManager.APP_START_MODE_NORMAL;
7923                }
7924            }
7925            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7926                    != AppOpsManager.MODE_ALLOWED) {
7927                return ActivityManager.APP_START_MODE_DELAYED;
7928            }
7929        }
7930        return ActivityManager.APP_START_MODE_NORMAL;
7931    }
7932
7933    private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
7934        ProviderInfo pi = null;
7935        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7936        if (cpr != null) {
7937            pi = cpr.info;
7938        } else {
7939            try {
7940                pi = AppGlobals.getPackageManager().resolveContentProvider(
7941                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
7942                        userHandle);
7943            } catch (RemoteException ex) {
7944            }
7945        }
7946        return pi;
7947    }
7948
7949    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7950        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7951        if (targetUris != null) {
7952            return targetUris.get(grantUri);
7953        }
7954        return null;
7955    }
7956
7957    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7958            String targetPkg, int targetUid, GrantUri grantUri) {
7959        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7960        if (targetUris == null) {
7961            targetUris = Maps.newArrayMap();
7962            mGrantedUriPermissions.put(targetUid, targetUris);
7963        }
7964
7965        UriPermission perm = targetUris.get(grantUri);
7966        if (perm == null) {
7967            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7968            targetUris.put(grantUri, perm);
7969        }
7970
7971        return perm;
7972    }
7973
7974    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7975            final int modeFlags) {
7976        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7977        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7978                : UriPermission.STRENGTH_OWNED;
7979
7980        // Root gets to do everything.
7981        if (uid == 0) {
7982            return true;
7983        }
7984
7985        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7986        if (perms == null) return false;
7987
7988        // First look for exact match
7989        final UriPermission exactPerm = perms.get(grantUri);
7990        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7991            return true;
7992        }
7993
7994        // No exact match, look for prefixes
7995        final int N = perms.size();
7996        for (int i = 0; i < N; i++) {
7997            final UriPermission perm = perms.valueAt(i);
7998            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7999                    && perm.getStrength(modeFlags) >= minStrength) {
8000                return true;
8001            }
8002        }
8003
8004        return false;
8005    }
8006
8007    /**
8008     * @param uri This uri must NOT contain an embedded userId.
8009     * @param userId The userId in which the uri is to be resolved.
8010     */
8011    @Override
8012    public int checkUriPermission(Uri uri, int pid, int uid,
8013            final int modeFlags, int userId, IBinder callerToken) {
8014        enforceNotIsolatedCaller("checkUriPermission");
8015
8016        // Another redirected-binder-call permissions check as in
8017        // {@link checkPermissionWithToken}.
8018        Identity tlsIdentity = sCallerIdentity.get();
8019        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8020            uid = tlsIdentity.uid;
8021            pid = tlsIdentity.pid;
8022        }
8023
8024        // Our own process gets to do everything.
8025        if (pid == MY_PID) {
8026            return PackageManager.PERMISSION_GRANTED;
8027        }
8028        synchronized (this) {
8029            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
8030                    ? PackageManager.PERMISSION_GRANTED
8031                    : PackageManager.PERMISSION_DENIED;
8032        }
8033    }
8034
8035    /**
8036     * Check if the targetPkg can be granted permission to access uri by
8037     * the callingUid using the given modeFlags.  Throws a security exception
8038     * if callingUid is not allowed to do this.  Returns the uid of the target
8039     * if the URI permission grant should be performed; returns -1 if it is not
8040     * needed (for example targetPkg already has permission to access the URI).
8041     * If you already know the uid of the target, you can supply it in
8042     * lastTargetUid else set that to -1.
8043     */
8044    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8045            final int modeFlags, int lastTargetUid) {
8046        if (!Intent.isAccessUriMode(modeFlags)) {
8047            return -1;
8048        }
8049
8050        if (targetPkg != null) {
8051            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8052                    "Checking grant " + targetPkg + " permission to " + grantUri);
8053        }
8054
8055        final IPackageManager pm = AppGlobals.getPackageManager();
8056
8057        // If this is not a content: uri, we can't do anything with it.
8058        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8059            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8060                    "Can't grant URI permission for non-content URI: " + grantUri);
8061            return -1;
8062        }
8063
8064        final String authority = grantUri.uri.getAuthority();
8065        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8066                MATCH_DEBUG_TRIAGED_MISSING);
8067        if (pi == null) {
8068            Slog.w(TAG, "No content provider found for permission check: " +
8069                    grantUri.uri.toSafeString());
8070            return -1;
8071        }
8072
8073        int targetUid = lastTargetUid;
8074        if (targetUid < 0 && targetPkg != null) {
8075            try {
8076                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8077                        UserHandle.getUserId(callingUid));
8078                if (targetUid < 0) {
8079                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8080                            "Can't grant URI permission no uid for: " + targetPkg);
8081                    return -1;
8082                }
8083            } catch (RemoteException ex) {
8084                return -1;
8085            }
8086        }
8087
8088        if (targetUid >= 0) {
8089            // First...  does the target actually need this permission?
8090            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8091                // No need to grant the target this permission.
8092                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8093                        "Target " + targetPkg + " already has full permission to " + grantUri);
8094                return -1;
8095            }
8096        } else {
8097            // First...  there is no target package, so can anyone access it?
8098            boolean allowed = pi.exported;
8099            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8100                if (pi.readPermission != null) {
8101                    allowed = false;
8102                }
8103            }
8104            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8105                if (pi.writePermission != null) {
8106                    allowed = false;
8107                }
8108            }
8109            if (allowed) {
8110                return -1;
8111            }
8112        }
8113
8114        /* There is a special cross user grant if:
8115         * - The target is on another user.
8116         * - Apps on the current user can access the uri without any uid permissions.
8117         * In this case, we grant a uri permission, even if the ContentProvider does not normally
8118         * grant uri permissions.
8119         */
8120        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8121                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8122                modeFlags, false /*without considering the uid permissions*/);
8123
8124        // Second...  is the provider allowing granting of URI permissions?
8125        if (!specialCrossUserGrant) {
8126            if (!pi.grantUriPermissions) {
8127                throw new SecurityException("Provider " + pi.packageName
8128                        + "/" + pi.name
8129                        + " does not allow granting of Uri permissions (uri "
8130                        + grantUri + ")");
8131            }
8132            if (pi.uriPermissionPatterns != null) {
8133                final int N = pi.uriPermissionPatterns.length;
8134                boolean allowed = false;
8135                for (int i=0; i<N; i++) {
8136                    if (pi.uriPermissionPatterns[i] != null
8137                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8138                        allowed = true;
8139                        break;
8140                    }
8141                }
8142                if (!allowed) {
8143                    throw new SecurityException("Provider " + pi.packageName
8144                            + "/" + pi.name
8145                            + " does not allow granting of permission to path of Uri "
8146                            + grantUri);
8147                }
8148            }
8149        }
8150
8151        // Third...  does the caller itself have permission to access
8152        // this uri?
8153        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
8154            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8155                // Require they hold a strong enough Uri permission
8156                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8157                    throw new SecurityException("Uid " + callingUid
8158                            + " does not have permission to uri " + grantUri);
8159                }
8160            }
8161        }
8162        return targetUid;
8163    }
8164
8165    /**
8166     * @param uri This uri must NOT contain an embedded userId.
8167     * @param userId The userId in which the uri is to be resolved.
8168     */
8169    @Override
8170    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8171            final int modeFlags, int userId) {
8172        enforceNotIsolatedCaller("checkGrantUriPermission");
8173        synchronized(this) {
8174            return checkGrantUriPermissionLocked(callingUid, targetPkg,
8175                    new GrantUri(userId, uri, false), modeFlags, -1);
8176        }
8177    }
8178
8179    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8180            final int modeFlags, UriPermissionOwner owner) {
8181        if (!Intent.isAccessUriMode(modeFlags)) {
8182            return;
8183        }
8184
8185        // So here we are: the caller has the assumed permission
8186        // to the uri, and the target doesn't.  Let's now give this to
8187        // the target.
8188
8189        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8190                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8191
8192        final String authority = grantUri.uri.getAuthority();
8193        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8194                MATCH_DEBUG_TRIAGED_MISSING);
8195        if (pi == null) {
8196            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8197            return;
8198        }
8199
8200        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8201            grantUri.prefix = true;
8202        }
8203        final UriPermission perm = findOrCreateUriPermissionLocked(
8204                pi.packageName, targetPkg, targetUid, grantUri);
8205        perm.grantModes(modeFlags, owner);
8206    }
8207
8208    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8209            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8210        if (targetPkg == null) {
8211            throw new NullPointerException("targetPkg");
8212        }
8213        int targetUid;
8214        final IPackageManager pm = AppGlobals.getPackageManager();
8215        try {
8216            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8217        } catch (RemoteException ex) {
8218            return;
8219        }
8220
8221        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8222                targetUid);
8223        if (targetUid < 0) {
8224            return;
8225        }
8226
8227        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8228                owner);
8229    }
8230
8231    static class NeededUriGrants extends ArrayList<GrantUri> {
8232        final String targetPkg;
8233        final int targetUid;
8234        final int flags;
8235
8236        NeededUriGrants(String targetPkg, int targetUid, int flags) {
8237            this.targetPkg = targetPkg;
8238            this.targetUid = targetUid;
8239            this.flags = flags;
8240        }
8241    }
8242
8243    /**
8244     * Like checkGrantUriPermissionLocked, but takes an Intent.
8245     */
8246    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8247            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8248        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8249                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8250                + " clip=" + (intent != null ? intent.getClipData() : null)
8251                + " from " + intent + "; flags=0x"
8252                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8253
8254        if (targetPkg == null) {
8255            throw new NullPointerException("targetPkg");
8256        }
8257
8258        if (intent == null) {
8259            return null;
8260        }
8261        Uri data = intent.getData();
8262        ClipData clip = intent.getClipData();
8263        if (data == null && clip == null) {
8264            return null;
8265        }
8266        // Default userId for uris in the intent (if they don't specify it themselves)
8267        int contentUserHint = intent.getContentUserHint();
8268        if (contentUserHint == UserHandle.USER_CURRENT) {
8269            contentUserHint = UserHandle.getUserId(callingUid);
8270        }
8271        final IPackageManager pm = AppGlobals.getPackageManager();
8272        int targetUid;
8273        if (needed != null) {
8274            targetUid = needed.targetUid;
8275        } else {
8276            try {
8277                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8278                        targetUserId);
8279            } catch (RemoteException ex) {
8280                return null;
8281            }
8282            if (targetUid < 0) {
8283                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8284                        "Can't grant URI permission no uid for: " + targetPkg
8285                        + " on user " + targetUserId);
8286                return null;
8287            }
8288        }
8289        if (data != null) {
8290            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8291            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8292                    targetUid);
8293            if (targetUid > 0) {
8294                if (needed == null) {
8295                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8296                }
8297                needed.add(grantUri);
8298            }
8299        }
8300        if (clip != null) {
8301            for (int i=0; i<clip.getItemCount(); i++) {
8302                Uri uri = clip.getItemAt(i).getUri();
8303                if (uri != null) {
8304                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8305                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8306                            targetUid);
8307                    if (targetUid > 0) {
8308                        if (needed == null) {
8309                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8310                        }
8311                        needed.add(grantUri);
8312                    }
8313                } else {
8314                    Intent clipIntent = clip.getItemAt(i).getIntent();
8315                    if (clipIntent != null) {
8316                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8317                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8318                        if (newNeeded != null) {
8319                            needed = newNeeded;
8320                        }
8321                    }
8322                }
8323            }
8324        }
8325
8326        return needed;
8327    }
8328
8329    /**
8330     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8331     */
8332    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8333            UriPermissionOwner owner) {
8334        if (needed != null) {
8335            for (int i=0; i<needed.size(); i++) {
8336                GrantUri grantUri = needed.get(i);
8337                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8338                        grantUri, needed.flags, owner);
8339            }
8340        }
8341    }
8342
8343    void grantUriPermissionFromIntentLocked(int callingUid,
8344            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8345        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8346                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8347        if (needed == null) {
8348            return;
8349        }
8350
8351        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8352    }
8353
8354    /**
8355     * @param uri This uri must NOT contain an embedded userId.
8356     * @param userId The userId in which the uri is to be resolved.
8357     */
8358    @Override
8359    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8360            final int modeFlags, int userId) {
8361        enforceNotIsolatedCaller("grantUriPermission");
8362        GrantUri grantUri = new GrantUri(userId, uri, false);
8363        synchronized(this) {
8364            final ProcessRecord r = getRecordForAppLocked(caller);
8365            if (r == null) {
8366                throw new SecurityException("Unable to find app for caller "
8367                        + caller
8368                        + " when granting permission to uri " + grantUri);
8369            }
8370            if (targetPkg == null) {
8371                throw new IllegalArgumentException("null target");
8372            }
8373            if (grantUri == null) {
8374                throw new IllegalArgumentException("null uri");
8375            }
8376
8377            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8378                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8379                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8380                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8381
8382            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8383                    UserHandle.getUserId(r.uid));
8384        }
8385    }
8386
8387    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8388        if (perm.modeFlags == 0) {
8389            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8390                    perm.targetUid);
8391            if (perms != null) {
8392                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8393                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8394
8395                perms.remove(perm.uri);
8396                if (perms.isEmpty()) {
8397                    mGrantedUriPermissions.remove(perm.targetUid);
8398                }
8399            }
8400        }
8401    }
8402
8403    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8404        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8405                "Revoking all granted permissions to " + grantUri);
8406
8407        final IPackageManager pm = AppGlobals.getPackageManager();
8408        final String authority = grantUri.uri.getAuthority();
8409        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8410                MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8411        if (pi == null) {
8412            Slog.w(TAG, "No content provider found for permission revoke: "
8413                    + grantUri.toSafeString());
8414            return;
8415        }
8416
8417        // Does the caller have this permission on the URI?
8418        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8419            // If they don't have direct access to the URI, then revoke any
8420            // ownerless URI permissions that have been granted to them.
8421            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8422            if (perms != null) {
8423                boolean persistChanged = false;
8424                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8425                    final UriPermission perm = it.next();
8426                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8427                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8428                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8429                                "Revoking non-owned " + perm.targetUid
8430                                + " permission to " + perm.uri);
8431                        persistChanged |= perm.revokeModes(
8432                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8433                        if (perm.modeFlags == 0) {
8434                            it.remove();
8435                        }
8436                    }
8437                }
8438                if (perms.isEmpty()) {
8439                    mGrantedUriPermissions.remove(callingUid);
8440                }
8441                if (persistChanged) {
8442                    schedulePersistUriGrants();
8443                }
8444            }
8445            return;
8446        }
8447
8448        boolean persistChanged = false;
8449
8450        // Go through all of the permissions and remove any that match.
8451        int N = mGrantedUriPermissions.size();
8452        for (int i = 0; i < N; i++) {
8453            final int targetUid = mGrantedUriPermissions.keyAt(i);
8454            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8455
8456            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8457                final UriPermission perm = it.next();
8458                if (perm.uri.sourceUserId == grantUri.sourceUserId
8459                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8460                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8461                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8462                    persistChanged |= perm.revokeModes(
8463                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8464                    if (perm.modeFlags == 0) {
8465                        it.remove();
8466                    }
8467                }
8468            }
8469
8470            if (perms.isEmpty()) {
8471                mGrantedUriPermissions.remove(targetUid);
8472                N--;
8473                i--;
8474            }
8475        }
8476
8477        if (persistChanged) {
8478            schedulePersistUriGrants();
8479        }
8480    }
8481
8482    /**
8483     * @param uri This uri must NOT contain an embedded userId.
8484     * @param userId The userId in which the uri is to be resolved.
8485     */
8486    @Override
8487    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8488            int userId) {
8489        enforceNotIsolatedCaller("revokeUriPermission");
8490        synchronized(this) {
8491            final ProcessRecord r = getRecordForAppLocked(caller);
8492            if (r == null) {
8493                throw new SecurityException("Unable to find app for caller "
8494                        + caller
8495                        + " when revoking permission to uri " + uri);
8496            }
8497            if (uri == null) {
8498                Slog.w(TAG, "revokeUriPermission: null uri");
8499                return;
8500            }
8501
8502            if (!Intent.isAccessUriMode(modeFlags)) {
8503                return;
8504            }
8505
8506            final String authority = uri.getAuthority();
8507            final ProviderInfo pi = getProviderInfoLocked(authority, userId,
8508                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8509            if (pi == null) {
8510                Slog.w(TAG, "No content provider found for permission revoke: "
8511                        + uri.toSafeString());
8512                return;
8513            }
8514
8515            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8516        }
8517    }
8518
8519    /**
8520     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8521     * given package.
8522     *
8523     * @param packageName Package name to match, or {@code null} to apply to all
8524     *            packages.
8525     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8526     *            to all users.
8527     * @param persistable If persistable grants should be removed.
8528     */
8529    private void removeUriPermissionsForPackageLocked(
8530            String packageName, int userHandle, boolean persistable) {
8531        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8532            throw new IllegalArgumentException("Must narrow by either package or user");
8533        }
8534
8535        boolean persistChanged = false;
8536
8537        int N = mGrantedUriPermissions.size();
8538        for (int i = 0; i < N; i++) {
8539            final int targetUid = mGrantedUriPermissions.keyAt(i);
8540            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8541
8542            // Only inspect grants matching user
8543            if (userHandle == UserHandle.USER_ALL
8544                    || userHandle == UserHandle.getUserId(targetUid)) {
8545                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8546                    final UriPermission perm = it.next();
8547
8548                    // Only inspect grants matching package
8549                    if (packageName == null || perm.sourcePkg.equals(packageName)
8550                            || perm.targetPkg.equals(packageName)) {
8551                        // Hacky solution as part of fixing a security bug; ignore
8552                        // grants associated with DownloadManager so we don't have
8553                        // to immediately launch it to regrant the permissions
8554                        if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
8555                                && !persistable) continue;
8556
8557                        persistChanged |= perm.revokeModes(persistable
8558                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8559
8560                        // Only remove when no modes remain; any persisted grants
8561                        // will keep this alive.
8562                        if (perm.modeFlags == 0) {
8563                            it.remove();
8564                        }
8565                    }
8566                }
8567
8568                if (perms.isEmpty()) {
8569                    mGrantedUriPermissions.remove(targetUid);
8570                    N--;
8571                    i--;
8572                }
8573            }
8574        }
8575
8576        if (persistChanged) {
8577            schedulePersistUriGrants();
8578        }
8579    }
8580
8581    @Override
8582    public IBinder newUriPermissionOwner(String name) {
8583        enforceNotIsolatedCaller("newUriPermissionOwner");
8584        synchronized(this) {
8585            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8586            return owner.getExternalTokenLocked();
8587        }
8588    }
8589
8590    @Override
8591    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8592        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8593        synchronized(this) {
8594            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8595            if (r == null) {
8596                throw new IllegalArgumentException("Activity does not exist; token="
8597                        + activityToken);
8598            }
8599            return r.getUriPermissionsLocked().getExternalTokenLocked();
8600        }
8601    }
8602    /**
8603     * @param uri This uri must NOT contain an embedded userId.
8604     * @param sourceUserId The userId in which the uri is to be resolved.
8605     * @param targetUserId The userId of the app that receives the grant.
8606     */
8607    @Override
8608    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8609            final int modeFlags, int sourceUserId, int targetUserId) {
8610        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8611                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8612                "grantUriPermissionFromOwner", null);
8613        synchronized(this) {
8614            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8615            if (owner == null) {
8616                throw new IllegalArgumentException("Unknown owner: " + token);
8617            }
8618            if (fromUid != Binder.getCallingUid()) {
8619                if (Binder.getCallingUid() != Process.myUid()) {
8620                    // Only system code can grant URI permissions on behalf
8621                    // of other users.
8622                    throw new SecurityException("nice try");
8623                }
8624            }
8625            if (targetPkg == null) {
8626                throw new IllegalArgumentException("null target");
8627            }
8628            if (uri == null) {
8629                throw new IllegalArgumentException("null uri");
8630            }
8631
8632            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8633                    modeFlags, owner, targetUserId);
8634        }
8635    }
8636
8637    /**
8638     * @param uri This uri must NOT contain an embedded userId.
8639     * @param userId The userId in which the uri is to be resolved.
8640     */
8641    @Override
8642    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8643        synchronized(this) {
8644            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8645            if (owner == null) {
8646                throw new IllegalArgumentException("Unknown owner: " + token);
8647            }
8648
8649            if (uri == null) {
8650                owner.removeUriPermissionsLocked(mode);
8651            } else {
8652                final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
8653                owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
8654            }
8655        }
8656    }
8657
8658    private void schedulePersistUriGrants() {
8659        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8660            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8661                    10 * DateUtils.SECOND_IN_MILLIS);
8662        }
8663    }
8664
8665    private void writeGrantedUriPermissions() {
8666        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8667
8668        // Snapshot permissions so we can persist without lock
8669        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8670        synchronized (this) {
8671            final int size = mGrantedUriPermissions.size();
8672            for (int i = 0; i < size; i++) {
8673                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8674                for (UriPermission perm : perms.values()) {
8675                    if (perm.persistedModeFlags != 0) {
8676                        persist.add(perm.snapshot());
8677                    }
8678                }
8679            }
8680        }
8681
8682        FileOutputStream fos = null;
8683        try {
8684            fos = mGrantFile.startWrite();
8685
8686            XmlSerializer out = new FastXmlSerializer();
8687            out.setOutput(fos, StandardCharsets.UTF_8.name());
8688            out.startDocument(null, true);
8689            out.startTag(null, TAG_URI_GRANTS);
8690            for (UriPermission.Snapshot perm : persist) {
8691                out.startTag(null, TAG_URI_GRANT);
8692                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8693                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8694                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8695                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8696                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8697                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8698                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8699                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8700                out.endTag(null, TAG_URI_GRANT);
8701            }
8702            out.endTag(null, TAG_URI_GRANTS);
8703            out.endDocument();
8704
8705            mGrantFile.finishWrite(fos);
8706        } catch (IOException e) {
8707            if (fos != null) {
8708                mGrantFile.failWrite(fos);
8709            }
8710        }
8711    }
8712
8713    private void readGrantedUriPermissionsLocked() {
8714        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8715
8716        final long now = System.currentTimeMillis();
8717
8718        FileInputStream fis = null;
8719        try {
8720            fis = mGrantFile.openRead();
8721            final XmlPullParser in = Xml.newPullParser();
8722            in.setInput(fis, StandardCharsets.UTF_8.name());
8723
8724            int type;
8725            while ((type = in.next()) != END_DOCUMENT) {
8726                final String tag = in.getName();
8727                if (type == START_TAG) {
8728                    if (TAG_URI_GRANT.equals(tag)) {
8729                        final int sourceUserId;
8730                        final int targetUserId;
8731                        final int userHandle = readIntAttribute(in,
8732                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8733                        if (userHandle != UserHandle.USER_NULL) {
8734                            // For backwards compatibility.
8735                            sourceUserId = userHandle;
8736                            targetUserId = userHandle;
8737                        } else {
8738                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8739                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8740                        }
8741                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8742                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8743                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8744                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8745                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8746                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8747
8748                        // Sanity check that provider still belongs to source package
8749                        // Both direct boot aware and unaware packages are fine as we
8750                        // will do filtering at query time to avoid multiple parsing.
8751                        final ProviderInfo pi = getProviderInfoLocked(
8752                                uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
8753                                        | MATCH_DIRECT_BOOT_UNAWARE);
8754                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8755                            int targetUid = -1;
8756                            try {
8757                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8758                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8759                            } catch (RemoteException e) {
8760                            }
8761                            if (targetUid != -1) {
8762                                final UriPermission perm = findOrCreateUriPermissionLocked(
8763                                        sourcePkg, targetPkg, targetUid,
8764                                        new GrantUri(sourceUserId, uri, prefix));
8765                                perm.initPersistedModes(modeFlags, createdTime);
8766                            }
8767                        } else {
8768                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8769                                    + " but instead found " + pi);
8770                        }
8771                    }
8772                }
8773            }
8774        } catch (FileNotFoundException e) {
8775            // Missing grants is okay
8776        } catch (IOException e) {
8777            Slog.wtf(TAG, "Failed reading Uri grants", e);
8778        } catch (XmlPullParserException e) {
8779            Slog.wtf(TAG, "Failed reading Uri grants", e);
8780        } finally {
8781            IoUtils.closeQuietly(fis);
8782        }
8783    }
8784
8785    /**
8786     * @param uri This uri must NOT contain an embedded userId.
8787     * @param userId The userId in which the uri is to be resolved.
8788     */
8789    @Override
8790    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8791        enforceNotIsolatedCaller("takePersistableUriPermission");
8792
8793        Preconditions.checkFlagsArgument(modeFlags,
8794                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8795
8796        synchronized (this) {
8797            final int callingUid = Binder.getCallingUid();
8798            boolean persistChanged = false;
8799            GrantUri grantUri = new GrantUri(userId, uri, false);
8800
8801            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8802                    new GrantUri(userId, uri, false));
8803            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8804                    new GrantUri(userId, uri, true));
8805
8806            final boolean exactValid = (exactPerm != null)
8807                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8808            final boolean prefixValid = (prefixPerm != null)
8809                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8810
8811            if (!(exactValid || prefixValid)) {
8812                throw new SecurityException("No persistable permission grants found for UID "
8813                        + callingUid + " and Uri " + grantUri.toSafeString());
8814            }
8815
8816            if (exactValid) {
8817                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8818            }
8819            if (prefixValid) {
8820                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8821            }
8822
8823            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8824
8825            if (persistChanged) {
8826                schedulePersistUriGrants();
8827            }
8828        }
8829    }
8830
8831    /**
8832     * @param uri This uri must NOT contain an embedded userId.
8833     * @param userId The userId in which the uri is to be resolved.
8834     */
8835    @Override
8836    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8837        enforceNotIsolatedCaller("releasePersistableUriPermission");
8838
8839        Preconditions.checkFlagsArgument(modeFlags,
8840                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8841
8842        synchronized (this) {
8843            final int callingUid = Binder.getCallingUid();
8844            boolean persistChanged = false;
8845
8846            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8847                    new GrantUri(userId, uri, false));
8848            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8849                    new GrantUri(userId, uri, true));
8850            if (exactPerm == null && prefixPerm == null) {
8851                throw new SecurityException("No permission grants found for UID " + callingUid
8852                        + " and Uri " + uri.toSafeString());
8853            }
8854
8855            if (exactPerm != null) {
8856                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8857                removeUriPermissionIfNeededLocked(exactPerm);
8858            }
8859            if (prefixPerm != null) {
8860                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8861                removeUriPermissionIfNeededLocked(prefixPerm);
8862            }
8863
8864            if (persistChanged) {
8865                schedulePersistUriGrants();
8866            }
8867        }
8868    }
8869
8870    /**
8871     * Prune any older {@link UriPermission} for the given UID until outstanding
8872     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8873     *
8874     * @return if any mutations occured that require persisting.
8875     */
8876    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8877        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8878        if (perms == null) return false;
8879        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8880
8881        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8882        for (UriPermission perm : perms.values()) {
8883            if (perm.persistedModeFlags != 0) {
8884                persisted.add(perm);
8885            }
8886        }
8887
8888        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8889        if (trimCount <= 0) return false;
8890
8891        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8892        for (int i = 0; i < trimCount; i++) {
8893            final UriPermission perm = persisted.get(i);
8894
8895            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8896                    "Trimming grant created at " + perm.persistedCreateTime);
8897
8898            perm.releasePersistableModes(~0);
8899            removeUriPermissionIfNeededLocked(perm);
8900        }
8901
8902        return true;
8903    }
8904
8905    @Override
8906    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8907            String packageName, boolean incoming) {
8908        enforceNotIsolatedCaller("getPersistedUriPermissions");
8909        Preconditions.checkNotNull(packageName, "packageName");
8910
8911        final int callingUid = Binder.getCallingUid();
8912        final int callingUserId = UserHandle.getUserId(callingUid);
8913        final IPackageManager pm = AppGlobals.getPackageManager();
8914        try {
8915            final int packageUid = pm.getPackageUid(packageName,
8916                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
8917            if (packageUid != callingUid) {
8918                throw new SecurityException(
8919                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8920            }
8921        } catch (RemoteException e) {
8922            throw new SecurityException("Failed to verify package name ownership");
8923        }
8924
8925        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8926        synchronized (this) {
8927            if (incoming) {
8928                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8929                        callingUid);
8930                if (perms == null) {
8931                    Slog.w(TAG, "No permission grants found for " + packageName);
8932                } else {
8933                    for (UriPermission perm : perms.values()) {
8934                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8935                            result.add(perm.buildPersistedPublicApiObject());
8936                        }
8937                    }
8938                }
8939            } else {
8940                final int size = mGrantedUriPermissions.size();
8941                for (int i = 0; i < size; i++) {
8942                    final ArrayMap<GrantUri, UriPermission> perms =
8943                            mGrantedUriPermissions.valueAt(i);
8944                    for (UriPermission perm : perms.values()) {
8945                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8946                            result.add(perm.buildPersistedPublicApiObject());
8947                        }
8948                    }
8949                }
8950            }
8951        }
8952        return new ParceledListSlice<android.content.UriPermission>(result);
8953    }
8954
8955    @Override
8956    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8957            String packageName, int userId) {
8958        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8959                "getGrantedUriPermissions");
8960
8961        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8962        synchronized (this) {
8963            final int size = mGrantedUriPermissions.size();
8964            for (int i = 0; i < size; i++) {
8965                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8966                for (UriPermission perm : perms.values()) {
8967                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8968                            && perm.persistedModeFlags != 0) {
8969                        result.add(perm.buildPersistedPublicApiObject());
8970                    }
8971                }
8972            }
8973        }
8974        return new ParceledListSlice<android.content.UriPermission>(result);
8975    }
8976
8977    @Override
8978    public void clearGrantedUriPermissions(String packageName, int userId) {
8979        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8980                "clearGrantedUriPermissions");
8981        removeUriPermissionsForPackageLocked(packageName, userId, true);
8982    }
8983
8984    @Override
8985    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8986        synchronized (this) {
8987            ProcessRecord app =
8988                who != null ? getRecordForAppLocked(who) : null;
8989            if (app == null) return;
8990
8991            Message msg = Message.obtain();
8992            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8993            msg.obj = app;
8994            msg.arg1 = waiting ? 1 : 0;
8995            mUiHandler.sendMessage(msg);
8996        }
8997    }
8998
8999    @Override
9000    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
9001        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
9002        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
9003        outInfo.availMem = Process.getFreeMemory();
9004        outInfo.totalMem = Process.getTotalMemory();
9005        outInfo.threshold = homeAppMem;
9006        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
9007        outInfo.hiddenAppThreshold = cachedAppMem;
9008        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
9009                ProcessList.SERVICE_ADJ);
9010        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
9011                ProcessList.VISIBLE_APP_ADJ);
9012        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
9013                ProcessList.FOREGROUND_APP_ADJ);
9014    }
9015
9016    // =========================================================
9017    // TASK MANAGEMENT
9018    // =========================================================
9019
9020    @Override
9021    public List<IAppTask> getAppTasks(String callingPackage) {
9022        int callingUid = Binder.getCallingUid();
9023        long ident = Binder.clearCallingIdentity();
9024
9025        synchronized(this) {
9026            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
9027            try {
9028                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
9029
9030                final int N = mRecentTasks.size();
9031                for (int i = 0; i < N; i++) {
9032                    TaskRecord tr = mRecentTasks.get(i);
9033                    // Skip tasks that do not match the caller.  We don't need to verify
9034                    // callingPackage, because we are also limiting to callingUid and know
9035                    // that will limit to the correct security sandbox.
9036                    if (tr.effectiveUid != callingUid) {
9037                        continue;
9038                    }
9039                    Intent intent = tr.getBaseIntent();
9040                    if (intent == null ||
9041                            !callingPackage.equals(intent.getComponent().getPackageName())) {
9042                        continue;
9043                    }
9044                    ActivityManager.RecentTaskInfo taskInfo =
9045                            createRecentTaskInfoFromTaskRecord(tr);
9046                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
9047                    list.add(taskImpl);
9048                }
9049            } finally {
9050                Binder.restoreCallingIdentity(ident);
9051            }
9052            return list;
9053        }
9054    }
9055
9056    @Override
9057    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9058        final int callingUid = Binder.getCallingUid();
9059        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9060
9061        synchronized(this) {
9062            if (DEBUG_ALL) Slog.v(
9063                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9064
9065            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9066                    callingUid);
9067
9068            // TODO: Improve with MRU list from all ActivityStacks.
9069            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9070        }
9071
9072        return list;
9073    }
9074
9075    /**
9076     * Creates a new RecentTaskInfo from a TaskRecord.
9077     */
9078    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9079        // Update the task description to reflect any changes in the task stack
9080        tr.updateTaskDescription();
9081
9082        // Compose the recent task info
9083        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9084        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9085        rti.persistentId = tr.taskId;
9086        rti.baseIntent = new Intent(tr.getBaseIntent());
9087        rti.origActivity = tr.origActivity;
9088        rti.realActivity = tr.realActivity;
9089        rti.description = tr.lastDescription;
9090        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
9091        rti.userId = tr.userId;
9092        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9093        rti.firstActiveTime = tr.firstActiveTime;
9094        rti.lastActiveTime = tr.lastActiveTime;
9095        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9096        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9097        rti.numActivities = 0;
9098        if (tr.mBounds != null) {
9099            rti.bounds = new Rect(tr.mBounds);
9100        }
9101        rti.isDockable = tr.canGoInDockedStack();
9102        rti.resizeMode = tr.mResizeMode;
9103
9104        ActivityRecord base = null;
9105        ActivityRecord top = null;
9106        ActivityRecord tmp;
9107
9108        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9109            tmp = tr.mActivities.get(i);
9110            if (tmp.finishing) {
9111                continue;
9112            }
9113            base = tmp;
9114            if (top == null || (top.state == ActivityState.INITIALIZING)) {
9115                top = base;
9116            }
9117            rti.numActivities++;
9118        }
9119
9120        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9121        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9122
9123        return rti;
9124    }
9125
9126    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9127        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9128                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9129        if (!allowed) {
9130            if (checkPermission(android.Manifest.permission.GET_TASKS,
9131                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9132                // Temporary compatibility: some existing apps on the system image may
9133                // still be requesting the old permission and not switched to the new
9134                // one; if so, we'll still allow them full access.  This means we need
9135                // to see if they are holding the old permission and are a system app.
9136                try {
9137                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9138                        allowed = true;
9139                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9140                                + " is using old GET_TASKS but privileged; allowing");
9141                    }
9142                } catch (RemoteException e) {
9143                }
9144            }
9145        }
9146        if (!allowed) {
9147            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9148                    + " does not hold REAL_GET_TASKS; limiting output");
9149        }
9150        return allowed;
9151    }
9152
9153    @Override
9154    public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9155            int userId) {
9156        final int callingUid = Binder.getCallingUid();
9157        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9158                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9159
9160        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9161        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9162        synchronized (this) {
9163            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9164                    callingUid);
9165            final boolean detailed = checkCallingPermission(
9166                    android.Manifest.permission.GET_DETAILED_TASKS)
9167                    == PackageManager.PERMISSION_GRANTED;
9168
9169            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9170                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9171                return ParceledListSlice.emptyList();
9172            }
9173            mRecentTasks.loadUserRecentsLocked(userId);
9174
9175            final int recentsCount = mRecentTasks.size();
9176            ArrayList<ActivityManager.RecentTaskInfo> res =
9177                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9178
9179            final Set<Integer> includedUsers;
9180            if (includeProfiles) {
9181                includedUsers = mUserController.getProfileIds(userId);
9182            } else {
9183                includedUsers = new HashSet<>();
9184            }
9185            includedUsers.add(Integer.valueOf(userId));
9186
9187            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9188                TaskRecord tr = mRecentTasks.get(i);
9189                // Only add calling user or related users recent tasks
9190                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9191                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9192                    continue;
9193                }
9194
9195                if (tr.realActivitySuspended) {
9196                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9197                    continue;
9198                }
9199
9200                // Return the entry if desired by the caller.  We always return
9201                // the first entry, because callers always expect this to be the
9202                // foreground app.  We may filter others if the caller has
9203                // not supplied RECENT_WITH_EXCLUDED and there is some reason
9204                // we should exclude the entry.
9205
9206                if (i == 0
9207                        || withExcluded
9208                        || (tr.intent == null)
9209                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9210                                == 0)) {
9211                    if (!allowed) {
9212                        // If the caller doesn't have the GET_TASKS permission, then only
9213                        // allow them to see a small subset of tasks -- their own and home.
9214                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9215                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9216                            continue;
9217                        }
9218                    }
9219                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
9220                        if (tr.stack != null && tr.stack.isHomeStack()) {
9221                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9222                                    "Skipping, home stack task: " + tr);
9223                            continue;
9224                        }
9225                    }
9226                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9227                        final ActivityStack stack = tr.stack;
9228                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9229                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9230                                    "Skipping, top task in docked stack: " + tr);
9231                            continue;
9232                        }
9233                    }
9234                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9235                        if (tr.stack != null && tr.stack.isPinnedStack()) {
9236                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9237                                    "Skipping, pinned stack task: " + tr);
9238                            continue;
9239                        }
9240                    }
9241                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9242                        // Don't include auto remove tasks that are finished or finishing.
9243                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9244                                "Skipping, auto-remove without activity: " + tr);
9245                        continue;
9246                    }
9247                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9248                            && !tr.isAvailable) {
9249                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9250                                "Skipping, unavail real act: " + tr);
9251                        continue;
9252                    }
9253
9254                    if (!tr.mUserSetupComplete) {
9255                        // Don't include task launched while user is not done setting-up.
9256                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9257                                "Skipping, user setup not complete: " + tr);
9258                        continue;
9259                    }
9260
9261                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9262                    if (!detailed) {
9263                        rti.baseIntent.replaceExtras((Bundle)null);
9264                    }
9265
9266                    res.add(rti);
9267                    maxNum--;
9268                }
9269            }
9270            return new ParceledListSlice<>(res);
9271        }
9272    }
9273
9274    @Override
9275    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9276        synchronized (this) {
9277            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9278                    "getTaskThumbnail()");
9279            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9280                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9281            if (tr != null) {
9282                return tr.getTaskThumbnailLocked();
9283            }
9284        }
9285        return null;
9286    }
9287
9288    @Override
9289    public int addAppTask(IBinder activityToken, Intent intent,
9290            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9291        final int callingUid = Binder.getCallingUid();
9292        final long callingIdent = Binder.clearCallingIdentity();
9293
9294        try {
9295            synchronized (this) {
9296                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9297                if (r == null) {
9298                    throw new IllegalArgumentException("Activity does not exist; token="
9299                            + activityToken);
9300                }
9301                ComponentName comp = intent.getComponent();
9302                if (comp == null) {
9303                    throw new IllegalArgumentException("Intent " + intent
9304                            + " must specify explicit component");
9305                }
9306                if (thumbnail.getWidth() != mThumbnailWidth
9307                        || thumbnail.getHeight() != mThumbnailHeight) {
9308                    throw new IllegalArgumentException("Bad thumbnail size: got "
9309                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9310                            + mThumbnailWidth + "x" + mThumbnailHeight);
9311                }
9312                if (intent.getSelector() != null) {
9313                    intent.setSelector(null);
9314                }
9315                if (intent.getSourceBounds() != null) {
9316                    intent.setSourceBounds(null);
9317                }
9318                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9319                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9320                        // The caller has added this as an auto-remove task...  that makes no
9321                        // sense, so turn off auto-remove.
9322                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9323                    }
9324                }
9325                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9326                    mLastAddedTaskActivity = null;
9327                }
9328                ActivityInfo ainfo = mLastAddedTaskActivity;
9329                if (ainfo == null) {
9330                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9331                            comp, 0, UserHandle.getUserId(callingUid));
9332                    if (ainfo.applicationInfo.uid != callingUid) {
9333                        throw new SecurityException(
9334                                "Can't add task for another application: target uid="
9335                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9336                    }
9337                }
9338
9339                // Use the full screen as the context for the task thumbnail
9340                final Point displaySize = new Point();
9341                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9342                r.task.stack.getDisplaySize(displaySize);
9343                thumbnailInfo.taskWidth = displaySize.x;
9344                thumbnailInfo.taskHeight = displaySize.y;
9345                thumbnailInfo.screenOrientation = mConfiguration.orientation;
9346
9347                TaskRecord task = new TaskRecord(this,
9348                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9349                        ainfo, intent, description, thumbnailInfo);
9350
9351                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9352                if (trimIdx >= 0) {
9353                    // If this would have caused a trim, then we'll abort because that
9354                    // means it would be added at the end of the list but then just removed.
9355                    return INVALID_TASK_ID;
9356                }
9357
9358                final int N = mRecentTasks.size();
9359                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9360                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9361                    tr.removedFromRecents();
9362                }
9363
9364                task.inRecents = true;
9365                mRecentTasks.add(task);
9366                r.task.stack.addTask(task, false, "addAppTask");
9367
9368                task.setLastThumbnailLocked(thumbnail);
9369                task.freeLastThumbnail();
9370
9371                return task.taskId;
9372            }
9373        } finally {
9374            Binder.restoreCallingIdentity(callingIdent);
9375        }
9376    }
9377
9378    @Override
9379    public Point getAppTaskThumbnailSize() {
9380        synchronized (this) {
9381            return new Point(mThumbnailWidth,  mThumbnailHeight);
9382        }
9383    }
9384
9385    @Override
9386    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9387        synchronized (this) {
9388            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9389            if (r != null) {
9390                r.setTaskDescription(td);
9391                r.task.updateTaskDescription();
9392            }
9393        }
9394    }
9395
9396    @Override
9397    public void setTaskResizeable(int taskId, int resizeableMode) {
9398        synchronized (this) {
9399            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9400                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9401            if (task == null) {
9402                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9403                return;
9404            }
9405            if (task.mResizeMode != resizeableMode) {
9406                task.mResizeMode = resizeableMode;
9407                mWindowManager.setTaskResizeable(taskId, resizeableMode);
9408                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9409                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9410            }
9411        }
9412    }
9413
9414    @Override
9415    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9416        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9417        long ident = Binder.clearCallingIdentity();
9418        try {
9419            synchronized (this) {
9420                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9421                if (task == null) {
9422                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9423                    return;
9424                }
9425                int stackId = task.stack.mStackId;
9426                // We allow the task to scroll instead of resizing if this is a non-resizeable task
9427                // in crop windows resize mode or if the task size is affected by the docked stack
9428                // changing size. No need to update configuration.
9429                if (bounds != null && task.inCropWindowsResizeMode()
9430                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
9431                    mWindowManager.scrollTask(task.taskId, bounds);
9432                    return;
9433                }
9434
9435                // Place the task in the right stack if it isn't there already based on
9436                // the requested bounds.
9437                // The stack transition logic is:
9438                // - a null bounds on a freeform task moves that task to fullscreen
9439                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9440                //   that task to freeform
9441                // - otherwise the task is not moved
9442                if (!StackId.isTaskResizeAllowed(stackId)) {
9443                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9444                }
9445                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9446                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9447                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9448                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9449                }
9450                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9451                if (stackId != task.stack.mStackId) {
9452                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9453                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9454                    preserveWindow = false;
9455                }
9456
9457                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9458                        false /* deferResume */);
9459            }
9460        } finally {
9461            Binder.restoreCallingIdentity(ident);
9462        }
9463    }
9464
9465    @Override
9466    public Rect getTaskBounds(int taskId) {
9467        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9468        long ident = Binder.clearCallingIdentity();
9469        Rect rect = new Rect();
9470        try {
9471            synchronized (this) {
9472                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9473                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9474                if (task == null) {
9475                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9476                    return rect;
9477                }
9478                if (task.stack != null) {
9479                    // Return the bounds from window manager since it will be adjusted for various
9480                    // things like the presense of a docked stack for tasks that aren't resizeable.
9481                    mWindowManager.getTaskBounds(task.taskId, rect);
9482                } else {
9483                    // Task isn't in window manager yet since it isn't associated with a stack.
9484                    // Return the persist value from activity manager
9485                    if (task.mBounds != null) {
9486                        rect.set(task.mBounds);
9487                    } else if (task.mLastNonFullscreenBounds != null) {
9488                        rect.set(task.mLastNonFullscreenBounds);
9489                    }
9490                }
9491            }
9492        } finally {
9493            Binder.restoreCallingIdentity(ident);
9494        }
9495        return rect;
9496    }
9497
9498    @Override
9499    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9500        if (userId != UserHandle.getCallingUserId()) {
9501            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9502                    "getTaskDescriptionIcon");
9503        }
9504        final File passedIconFile = new File(filePath);
9505        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9506                passedIconFile.getName());
9507        if (!legitIconFile.getPath().equals(filePath)
9508                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9509            throw new IllegalArgumentException("Bad file path: " + filePath
9510                    + " passed for userId " + userId);
9511        }
9512        return mRecentTasks.getTaskDescriptionIcon(filePath);
9513    }
9514
9515    @Override
9516    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9517            throws RemoteException {
9518        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9519                opts.getCustomInPlaceResId() == 0) {
9520            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9521                    "with valid animation");
9522        }
9523        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9524        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9525                opts.getCustomInPlaceResId());
9526        mWindowManager.executeAppTransition();
9527    }
9528
9529    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9530            boolean removeFromRecents) {
9531        if (removeFromRecents) {
9532            mRecentTasks.remove(tr);
9533            tr.removedFromRecents();
9534        }
9535        ComponentName component = tr.getBaseIntent().getComponent();
9536        if (component == null) {
9537            Slog.w(TAG, "No component for base intent of task: " + tr);
9538            return;
9539        }
9540
9541        // Find any running services associated with this app and stop if needed.
9542        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9543
9544        if (!killProcess) {
9545            return;
9546        }
9547
9548        // Determine if the process(es) for this task should be killed.
9549        final String pkg = component.getPackageName();
9550        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9551        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9552        for (int i = 0; i < pmap.size(); i++) {
9553
9554            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9555            for (int j = 0; j < uids.size(); j++) {
9556                ProcessRecord proc = uids.valueAt(j);
9557                if (proc.userId != tr.userId) {
9558                    // Don't kill process for a different user.
9559                    continue;
9560                }
9561                if (proc == mHomeProcess) {
9562                    // Don't kill the home process along with tasks from the same package.
9563                    continue;
9564                }
9565                if (!proc.pkgList.containsKey(pkg)) {
9566                    // Don't kill process that is not associated with this task.
9567                    continue;
9568                }
9569
9570                for (int k = 0; k < proc.activities.size(); k++) {
9571                    TaskRecord otherTask = proc.activities.get(k).task;
9572                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9573                        // Don't kill process(es) that has an activity in a different task that is
9574                        // also in recents.
9575                        return;
9576                    }
9577                }
9578
9579                if (proc.foregroundServices) {
9580                    // Don't kill process(es) with foreground service.
9581                    return;
9582                }
9583
9584                // Add process to kill list.
9585                procsToKill.add(proc);
9586            }
9587        }
9588
9589        // Kill the running processes.
9590        for (int i = 0; i < procsToKill.size(); i++) {
9591            ProcessRecord pr = procsToKill.get(i);
9592            if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9593                    && pr.curReceiver == null) {
9594                pr.kill("remove task", true);
9595            } else {
9596                // We delay killing processes that are not in the background or running a receiver.
9597                pr.waitingToKill = "remove task";
9598            }
9599        }
9600    }
9601
9602    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9603        // Remove all tasks with activities in the specified package from the list of recent tasks
9604        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9605            TaskRecord tr = mRecentTasks.get(i);
9606            if (tr.userId != userId) continue;
9607
9608            ComponentName cn = tr.intent.getComponent();
9609            if (cn != null && cn.getPackageName().equals(packageName)) {
9610                // If the package name matches, remove the task.
9611                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9612            }
9613        }
9614    }
9615
9616    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9617            int userId) {
9618
9619        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9620            TaskRecord tr = mRecentTasks.get(i);
9621            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9622                continue;
9623            }
9624
9625            ComponentName cn = tr.intent.getComponent();
9626            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9627                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9628            if (sameComponent) {
9629                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9630            }
9631        }
9632    }
9633
9634    /**
9635     * Removes the task with the specified task id.
9636     *
9637     * @param taskId Identifier of the task to be removed.
9638     * @param killProcess Kill any process associated with the task if possible.
9639     * @param removeFromRecents Whether to also remove the task from recents.
9640     * @return Returns true if the given task was found and removed.
9641     */
9642    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9643            boolean removeFromRecents) {
9644        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9645                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9646        if (tr != null) {
9647            tr.removeTaskActivitiesLocked();
9648            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9649            if (tr.isPersistable) {
9650                notifyTaskPersisterLocked(null, true);
9651            }
9652            return true;
9653        }
9654        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9655        return false;
9656    }
9657
9658    @Override
9659    public void removeStack(int stackId) {
9660        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9661        if (stackId == HOME_STACK_ID) {
9662            throw new IllegalArgumentException("Removing home stack is not allowed.");
9663        }
9664
9665        synchronized (this) {
9666            final long ident = Binder.clearCallingIdentity();
9667            try {
9668                final ActivityStack stack = mStackSupervisor.getStack(stackId);
9669                if (stack == null) {
9670                    return;
9671                }
9672                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9673                for (int i = tasks.size() - 1; i >= 0; i--) {
9674                    removeTaskByIdLocked(
9675                            tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9676                }
9677            } finally {
9678                Binder.restoreCallingIdentity(ident);
9679            }
9680        }
9681    }
9682
9683    @Override
9684    public boolean removeTask(int taskId) {
9685        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9686        synchronized (this) {
9687            final long ident = Binder.clearCallingIdentity();
9688            try {
9689                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9690            } finally {
9691                Binder.restoreCallingIdentity(ident);
9692            }
9693        }
9694    }
9695
9696    /**
9697     * TODO: Add mController hook
9698     */
9699    @Override
9700    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9701        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9702
9703        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9704        synchronized(this) {
9705            moveTaskToFrontLocked(taskId, flags, bOptions);
9706        }
9707    }
9708
9709    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9710        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9711
9712        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9713                Binder.getCallingUid(), -1, -1, "Task to front")) {
9714            ActivityOptions.abort(options);
9715            return;
9716        }
9717        final long origId = Binder.clearCallingIdentity();
9718        try {
9719            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9720            if (task == null) {
9721                Slog.d(TAG, "Could not find task for id: "+ taskId);
9722                return;
9723            }
9724            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9725                mStackSupervisor.showLockTaskToast();
9726                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9727                return;
9728            }
9729            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9730            if (prev != null && prev.isRecentsActivity()) {
9731                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9732            }
9733            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9734                    false /* forceNonResizable */);
9735        } finally {
9736            Binder.restoreCallingIdentity(origId);
9737        }
9738        ActivityOptions.abort(options);
9739    }
9740
9741    /**
9742     * Moves an activity, and all of the other activities within the same task, to the bottom
9743     * of the history stack.  The activity's order within the task is unchanged.
9744     *
9745     * @param token A reference to the activity we wish to move
9746     * @param nonRoot If false then this only works if the activity is the root
9747     *                of a task; if true it will work for any activity in a task.
9748     * @return Returns true if the move completed, false if not.
9749     */
9750    @Override
9751    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9752        enforceNotIsolatedCaller("moveActivityTaskToBack");
9753        synchronized(this) {
9754            final long origId = Binder.clearCallingIdentity();
9755            try {
9756                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9757                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9758                if (task != null) {
9759                    if (mStackSupervisor.isLockedTask(task)) {
9760                        mStackSupervisor.showLockTaskToast();
9761                        return false;
9762                    }
9763                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9764                }
9765            } finally {
9766                Binder.restoreCallingIdentity(origId);
9767            }
9768        }
9769        return false;
9770    }
9771
9772    @Override
9773    public void moveTaskBackwards(int task) {
9774        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9775                "moveTaskBackwards()");
9776
9777        synchronized(this) {
9778            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9779                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9780                return;
9781            }
9782            final long origId = Binder.clearCallingIdentity();
9783            moveTaskBackwardsLocked(task);
9784            Binder.restoreCallingIdentity(origId);
9785        }
9786    }
9787
9788    private final void moveTaskBackwardsLocked(int task) {
9789        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9790    }
9791
9792    @Override
9793    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9794            IActivityContainerCallback callback) throws RemoteException {
9795        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9796        synchronized (this) {
9797            if (parentActivityToken == null) {
9798                throw new IllegalArgumentException("parent token must not be null");
9799            }
9800            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9801            if (r == null) {
9802                return null;
9803            }
9804            if (callback == null) {
9805                throw new IllegalArgumentException("callback must not be null");
9806            }
9807            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9808        }
9809    }
9810
9811    @Override
9812    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9813        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9814        synchronized (this) {
9815            mStackSupervisor.deleteActivityContainer(container);
9816        }
9817    }
9818
9819    @Override
9820    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9821        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9822        synchronized (this) {
9823            final int stackId = mStackSupervisor.getNextStackId();
9824            final ActivityStack stack =
9825                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9826            if (stack == null) {
9827                return null;
9828            }
9829            return stack.mActivityContainer;
9830        }
9831    }
9832
9833    @Override
9834    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9835        synchronized (this) {
9836            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9837            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9838                return stack.mActivityContainer.getDisplayId();
9839            }
9840            return Display.DEFAULT_DISPLAY;
9841        }
9842    }
9843
9844    @Override
9845    public int getActivityStackId(IBinder token) throws RemoteException {
9846        synchronized (this) {
9847            ActivityStack stack = ActivityRecord.getStackLocked(token);
9848            if (stack == null) {
9849                return INVALID_STACK_ID;
9850            }
9851            return stack.mStackId;
9852        }
9853    }
9854
9855    @Override
9856    public void exitFreeformMode(IBinder token) throws RemoteException {
9857        synchronized (this) {
9858            long ident = Binder.clearCallingIdentity();
9859            try {
9860                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9861                if (r == null) {
9862                    throw new IllegalArgumentException(
9863                            "exitFreeformMode: No activity record matching token=" + token);
9864                }
9865                final ActivityStack stack = r.getStackLocked(token);
9866                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9867                    throw new IllegalStateException(
9868                            "exitFreeformMode: You can only go fullscreen from freeform.");
9869                }
9870                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9871                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9872                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9873            } finally {
9874                Binder.restoreCallingIdentity(ident);
9875            }
9876        }
9877    }
9878
9879    @Override
9880    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9881        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9882        if (stackId == HOME_STACK_ID) {
9883            throw new IllegalArgumentException(
9884                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9885        }
9886        synchronized (this) {
9887            long ident = Binder.clearCallingIdentity();
9888            try {
9889                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9890                        + " to stackId=" + stackId + " toTop=" + toTop);
9891                if (stackId == DOCKED_STACK_ID) {
9892                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9893                            null /* initialBounds */);
9894                }
9895                boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9896                        !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9897                if (result && stackId == DOCKED_STACK_ID) {
9898                    // If task moved to docked stack - show recents if needed.
9899                    mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9900                            "moveTaskToDockedStack");
9901                }
9902            } finally {
9903                Binder.restoreCallingIdentity(ident);
9904            }
9905        }
9906    }
9907
9908    @Override
9909    public void swapDockedAndFullscreenStack() throws RemoteException {
9910        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9911        synchronized (this) {
9912            long ident = Binder.clearCallingIdentity();
9913            try {
9914                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9915                        FULLSCREEN_WORKSPACE_STACK_ID);
9916                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9917                        : null;
9918                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9919                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9920                        : null;
9921                if (topTask == null || tasks == null || tasks.size() == 0) {
9922                    Slog.w(TAG,
9923                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
9924                    return;
9925                }
9926
9927                // TODO: App transition
9928                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9929
9930                // Defer the resume so resume/pausing while moving stacks is dangerous.
9931                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9932                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9933                        ANIMATE, true /* deferResume */);
9934                final int size = tasks.size();
9935                for (int i = 0; i < size; i++) {
9936                    final int id = tasks.get(i).taskId;
9937                    if (id == topTask.taskId) {
9938                        continue;
9939                    }
9940                    mStackSupervisor.moveTaskToStackLocked(id,
9941                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9942                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9943                }
9944
9945                // Because we deferred the resume, to avoid conflicts with stack switches while
9946                // resuming, we need to do it after all the tasks are moved.
9947                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9948                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9949
9950                mWindowManager.executeAppTransition();
9951            } finally {
9952                Binder.restoreCallingIdentity(ident);
9953            }
9954        }
9955    }
9956
9957    /**
9958     * Moves the input task to the docked stack.
9959     *
9960     * @param taskId Id of task to move.
9961     * @param createMode The mode the docked stack should be created in if it doesn't exist
9962     *                   already. See
9963     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9964     *                   and
9965     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9966     * @param toTop If the task and stack should be moved to the top.
9967     * @param animate Whether we should play an animation for the moving the task
9968     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9969     *                      docked stack. Pass {@code null} to use default bounds.
9970     */
9971    @Override
9972    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9973            Rect initialBounds, boolean moveHomeStackFront) {
9974        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9975        synchronized (this) {
9976            long ident = Binder.clearCallingIdentity();
9977            try {
9978                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9979                        + " to createMode=" + createMode + " toTop=" + toTop);
9980                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9981                final boolean moved = mStackSupervisor.moveTaskToStackLocked(
9982                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
9983                        animate, DEFER_RESUME);
9984                if (moved) {
9985                    if (moveHomeStackFront) {
9986                        mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
9987                    }
9988                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9989                }
9990                return moved;
9991            } finally {
9992                Binder.restoreCallingIdentity(ident);
9993            }
9994        }
9995    }
9996
9997    /**
9998     * Moves the top activity in the input stackId to the pinned stack.
9999     *
10000     * @param stackId Id of stack to move the top activity to pinned stack.
10001     * @param bounds Bounds to use for pinned stack.
10002     *
10003     * @return True if the top activity of the input stack was successfully moved to the pinned
10004     *          stack.
10005     */
10006    @Override
10007    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
10008        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
10009        synchronized (this) {
10010            if (!mSupportsPictureInPicture) {
10011                throw new IllegalStateException("moveTopActivityToPinnedStack:"
10012                        + "Device doesn't support picture-in-pciture mode");
10013            }
10014
10015            long ident = Binder.clearCallingIdentity();
10016            try {
10017                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
10018            } finally {
10019                Binder.restoreCallingIdentity(ident);
10020            }
10021        }
10022    }
10023
10024    @Override
10025    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
10026            boolean preserveWindows, boolean animate, int animationDuration) {
10027        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
10028        long ident = Binder.clearCallingIdentity();
10029        try {
10030            synchronized (this) {
10031                if (animate) {
10032                    if (stackId == PINNED_STACK_ID) {
10033                        mWindowManager.animateResizePinnedStack(bounds, animationDuration);
10034                    } else {
10035                        throw new IllegalArgumentException("Stack: " + stackId
10036                                + " doesn't support animated resize.");
10037                    }
10038                } else {
10039                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
10040                            null /* tempTaskInsetBounds */, preserveWindows,
10041                            allowResizeInDockedMode, !DEFER_RESUME);
10042                }
10043            }
10044        } finally {
10045            Binder.restoreCallingIdentity(ident);
10046        }
10047    }
10048
10049    @Override
10050    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10051            Rect tempDockedTaskInsetBounds,
10052            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10053        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10054                "resizeDockedStack()");
10055        long ident = Binder.clearCallingIdentity();
10056        try {
10057            synchronized (this) {
10058                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10059                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10060                        PRESERVE_WINDOWS);
10061            }
10062        } finally {
10063            Binder.restoreCallingIdentity(ident);
10064        }
10065    }
10066
10067    @Override
10068    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10069        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10070                "resizePinnedStack()");
10071        final long ident = Binder.clearCallingIdentity();
10072        try {
10073            synchronized (this) {
10074                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10075            }
10076        } finally {
10077            Binder.restoreCallingIdentity(ident);
10078        }
10079    }
10080
10081    @Override
10082    public void positionTaskInStack(int taskId, int stackId, int position) {
10083        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10084        if (stackId == HOME_STACK_ID) {
10085            throw new IllegalArgumentException(
10086                    "positionTaskInStack: Attempt to change the position of task "
10087                    + taskId + " in/to home stack");
10088        }
10089        synchronized (this) {
10090            long ident = Binder.clearCallingIdentity();
10091            try {
10092                if (DEBUG_STACK) Slog.d(TAG_STACK,
10093                        "positionTaskInStack: positioning task=" + taskId
10094                        + " in stackId=" + stackId + " at position=" + position);
10095                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
10096            } finally {
10097                Binder.restoreCallingIdentity(ident);
10098            }
10099        }
10100    }
10101
10102    @Override
10103    public List<StackInfo> getAllStackInfos() {
10104        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10105        long ident = Binder.clearCallingIdentity();
10106        try {
10107            synchronized (this) {
10108                return mStackSupervisor.getAllStackInfosLocked();
10109            }
10110        } finally {
10111            Binder.restoreCallingIdentity(ident);
10112        }
10113    }
10114
10115    @Override
10116    public StackInfo getStackInfo(int stackId) {
10117        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10118        long ident = Binder.clearCallingIdentity();
10119        try {
10120            synchronized (this) {
10121                return mStackSupervisor.getStackInfoLocked(stackId);
10122            }
10123        } finally {
10124            Binder.restoreCallingIdentity(ident);
10125        }
10126    }
10127
10128    @Override
10129    public boolean isInHomeStack(int taskId) {
10130        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10131        long ident = Binder.clearCallingIdentity();
10132        try {
10133            synchronized (this) {
10134                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10135                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
10136                return tr != null && tr.stack != null && tr.stack.isHomeStack();
10137            }
10138        } finally {
10139            Binder.restoreCallingIdentity(ident);
10140        }
10141    }
10142
10143    @Override
10144    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10145        synchronized(this) {
10146            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10147        }
10148    }
10149
10150    @Override
10151    public void updateDeviceOwner(String packageName) {
10152        final int callingUid = Binder.getCallingUid();
10153        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10154            throw new SecurityException("updateDeviceOwner called from non-system process");
10155        }
10156        synchronized (this) {
10157            mDeviceOwnerName = packageName;
10158        }
10159    }
10160
10161    @Override
10162    public void updateLockTaskPackages(int userId, String[] packages) {
10163        final int callingUid = Binder.getCallingUid();
10164        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10165            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10166                    "updateLockTaskPackages()");
10167        }
10168        synchronized (this) {
10169            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10170                    Arrays.toString(packages));
10171            mLockTaskPackages.put(userId, packages);
10172            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10173        }
10174    }
10175
10176
10177    void startLockTaskModeLocked(TaskRecord task) {
10178        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10179        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10180            return;
10181        }
10182
10183        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10184        // is initiated by system after the pinning request was shown and locked mode is initiated
10185        // by an authorized app directly
10186        final int callingUid = Binder.getCallingUid();
10187        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10188        long ident = Binder.clearCallingIdentity();
10189        try {
10190            if (!isSystemInitiated) {
10191                task.mLockTaskUid = callingUid;
10192                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10193                    // startLockTask() called by app and task mode is lockTaskModeDefault.
10194                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10195                    StatusBarManagerInternal statusBarManager =
10196                            LocalServices.getService(StatusBarManagerInternal.class);
10197                    if (statusBarManager != null) {
10198                        statusBarManager.showScreenPinningRequest(task.taskId);
10199                    }
10200                    return;
10201                }
10202
10203                final ActivityStack stack = mStackSupervisor.getFocusedStack();
10204                if (stack == null || task != stack.topTask()) {
10205                    throw new IllegalArgumentException("Invalid task, not in foreground");
10206                }
10207            }
10208            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10209                    "Locking fully");
10210            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10211                    ActivityManager.LOCK_TASK_MODE_PINNED :
10212                    ActivityManager.LOCK_TASK_MODE_LOCKED,
10213                    "startLockTask", true);
10214        } finally {
10215            Binder.restoreCallingIdentity(ident);
10216        }
10217    }
10218
10219    @Override
10220    public void startLockTaskMode(int taskId) {
10221        synchronized (this) {
10222            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10223            if (task != null) {
10224                startLockTaskModeLocked(task);
10225            }
10226        }
10227    }
10228
10229    @Override
10230    public void startLockTaskMode(IBinder token) {
10231        synchronized (this) {
10232            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10233            if (r == null) {
10234                return;
10235            }
10236            final TaskRecord task = r.task;
10237            if (task != null) {
10238                startLockTaskModeLocked(task);
10239            }
10240        }
10241    }
10242
10243    @Override
10244    public void startSystemLockTaskMode(int taskId) throws RemoteException {
10245        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10246        // This makes inner call to look as if it was initiated by system.
10247        long ident = Binder.clearCallingIdentity();
10248        try {
10249            synchronized (this) {
10250                startLockTaskMode(taskId);
10251            }
10252        } finally {
10253            Binder.restoreCallingIdentity(ident);
10254        }
10255    }
10256
10257    @Override
10258    public void stopLockTaskMode() {
10259        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10260        if (lockTask == null) {
10261            // Our work here is done.
10262            return;
10263        }
10264
10265        final int callingUid = Binder.getCallingUid();
10266        final int lockTaskUid = lockTask.mLockTaskUid;
10267        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10268        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10269            // Done.
10270            return;
10271        } else {
10272            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10273            // It is possible lockTaskMode was started by the system process because
10274            // android:lockTaskMode is set to a locking value in the application manifest
10275            // instead of the app calling startLockTaskMode. In this case
10276            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10277            // {@link TaskRecord.effectiveUid} instead. Also caller with
10278            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10279            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10280                    && callingUid != lockTaskUid
10281                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10282                throw new SecurityException("Invalid uid, expected " + lockTaskUid
10283                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10284            }
10285        }
10286        long ident = Binder.clearCallingIdentity();
10287        try {
10288            Log.d(TAG, "stopLockTaskMode");
10289            // Stop lock task
10290            synchronized (this) {
10291                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10292                        "stopLockTask", true);
10293            }
10294            TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10295            if (tm != null) {
10296                tm.showInCallScreen(false);
10297            }
10298        } finally {
10299            Binder.restoreCallingIdentity(ident);
10300        }
10301    }
10302
10303    /**
10304     * This API should be called by SystemUI only when user perform certain action to dismiss
10305     * lock task mode. We should only dismiss pinned lock task mode in this case.
10306     */
10307    @Override
10308    public void stopSystemLockTaskMode() throws RemoteException {
10309        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10310            stopLockTaskMode();
10311        } else {
10312            mStackSupervisor.showLockTaskToast();
10313        }
10314    }
10315
10316    @Override
10317    public boolean isInLockTaskMode() {
10318        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10319    }
10320
10321    @Override
10322    public int getLockTaskModeState() {
10323        synchronized (this) {
10324            return mStackSupervisor.getLockTaskModeState();
10325        }
10326    }
10327
10328    @Override
10329    public void showLockTaskEscapeMessage(IBinder token) {
10330        synchronized (this) {
10331            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10332            if (r == null) {
10333                return;
10334            }
10335            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10336        }
10337    }
10338
10339    // =========================================================
10340    // CONTENT PROVIDERS
10341    // =========================================================
10342
10343    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10344        List<ProviderInfo> providers = null;
10345        try {
10346            providers = AppGlobals.getPackageManager()
10347                    .queryContentProviders(app.processName, app.uid,
10348                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10349                                    | MATCH_DEBUG_TRIAGED_MISSING)
10350                    .getList();
10351        } catch (RemoteException ex) {
10352        }
10353        if (DEBUG_MU) Slog.v(TAG_MU,
10354                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10355        int userId = app.userId;
10356        if (providers != null) {
10357            int N = providers.size();
10358            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10359            for (int i=0; i<N; i++) {
10360                // TODO: keep logic in sync with installEncryptionUnawareProviders
10361                ProviderInfo cpi =
10362                    (ProviderInfo)providers.get(i);
10363                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10364                        cpi.name, cpi.flags);
10365                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10366                    // This is a singleton provider, but a user besides the
10367                    // default user is asking to initialize a process it runs
10368                    // in...  well, no, it doesn't actually run in this process,
10369                    // it runs in the process of the default user.  Get rid of it.
10370                    providers.remove(i);
10371                    N--;
10372                    i--;
10373                    continue;
10374                }
10375
10376                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10377                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10378                if (cpr == null) {
10379                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10380                    mProviderMap.putProviderByClass(comp, cpr);
10381                }
10382                if (DEBUG_MU) Slog.v(TAG_MU,
10383                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10384                app.pubProviders.put(cpi.name, cpr);
10385                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10386                    // Don't add this if it is a platform component that is marked
10387                    // to run in multiple processes, because this is actually
10388                    // part of the framework so doesn't make sense to track as a
10389                    // separate apk in the process.
10390                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10391                            mProcessStats);
10392                }
10393                notifyPackageUse(cpi.applicationInfo.packageName,
10394                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10395            }
10396        }
10397        return providers;
10398    }
10399
10400    /**
10401     * Check if {@link ProcessRecord} has a possible chance at accessing the
10402     * given {@link ProviderInfo}. Final permission checking is always done
10403     * in {@link ContentProvider}.
10404     */
10405    private final String checkContentProviderPermissionLocked(
10406            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10407        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10408        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10409        boolean checkedGrants = false;
10410        if (checkUser) {
10411            // Looking for cross-user grants before enforcing the typical cross-users permissions
10412            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10413            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10414                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10415                    return null;
10416                }
10417                checkedGrants = true;
10418            }
10419            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10420                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10421            if (userId != tmpTargetUserId) {
10422                // When we actually went to determine the final targer user ID, this ended
10423                // up different than our initial check for the authority.  This is because
10424                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10425                // SELF.  So we need to re-check the grants again.
10426                checkedGrants = false;
10427            }
10428        }
10429        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10430                cpi.applicationInfo.uid, cpi.exported)
10431                == PackageManager.PERMISSION_GRANTED) {
10432            return null;
10433        }
10434        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10435                cpi.applicationInfo.uid, cpi.exported)
10436                == PackageManager.PERMISSION_GRANTED) {
10437            return null;
10438        }
10439
10440        PathPermission[] pps = cpi.pathPermissions;
10441        if (pps != null) {
10442            int i = pps.length;
10443            while (i > 0) {
10444                i--;
10445                PathPermission pp = pps[i];
10446                String pprperm = pp.getReadPermission();
10447                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10448                        cpi.applicationInfo.uid, cpi.exported)
10449                        == PackageManager.PERMISSION_GRANTED) {
10450                    return null;
10451                }
10452                String ppwperm = pp.getWritePermission();
10453                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10454                        cpi.applicationInfo.uid, cpi.exported)
10455                        == PackageManager.PERMISSION_GRANTED) {
10456                    return null;
10457                }
10458            }
10459        }
10460        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10461            return null;
10462        }
10463
10464        String msg;
10465        if (!cpi.exported) {
10466            msg = "Permission Denial: opening provider " + cpi.name
10467                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10468                    + ", uid=" + callingUid + ") that is not exported from uid "
10469                    + cpi.applicationInfo.uid;
10470        } else {
10471            msg = "Permission Denial: opening provider " + cpi.name
10472                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10473                    + ", uid=" + callingUid + ") requires "
10474                    + cpi.readPermission + " or " + cpi.writePermission;
10475        }
10476        Slog.w(TAG, msg);
10477        return msg;
10478    }
10479
10480    /**
10481     * Returns if the ContentProvider has granted a uri to callingUid
10482     */
10483    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10484        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10485        if (perms != null) {
10486            for (int i=perms.size()-1; i>=0; i--) {
10487                GrantUri grantUri = perms.keyAt(i);
10488                if (grantUri.sourceUserId == userId || !checkUser) {
10489                    if (matchesProvider(grantUri.uri, cpi)) {
10490                        return true;
10491                    }
10492                }
10493            }
10494        }
10495        return false;
10496    }
10497
10498    /**
10499     * Returns true if the uri authority is one of the authorities specified in the provider.
10500     */
10501    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10502        String uriAuth = uri.getAuthority();
10503        String cpiAuth = cpi.authority;
10504        if (cpiAuth.indexOf(';') == -1) {
10505            return cpiAuth.equals(uriAuth);
10506        }
10507        String[] cpiAuths = cpiAuth.split(";");
10508        int length = cpiAuths.length;
10509        for (int i = 0; i < length; i++) {
10510            if (cpiAuths[i].equals(uriAuth)) return true;
10511        }
10512        return false;
10513    }
10514
10515    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10516            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10517        if (r != null) {
10518            for (int i=0; i<r.conProviders.size(); i++) {
10519                ContentProviderConnection conn = r.conProviders.get(i);
10520                if (conn.provider == cpr) {
10521                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10522                            "Adding provider requested by "
10523                            + r.processName + " from process "
10524                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10525                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10526                    if (stable) {
10527                        conn.stableCount++;
10528                        conn.numStableIncs++;
10529                    } else {
10530                        conn.unstableCount++;
10531                        conn.numUnstableIncs++;
10532                    }
10533                    return conn;
10534                }
10535            }
10536            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10537            if (stable) {
10538                conn.stableCount = 1;
10539                conn.numStableIncs = 1;
10540            } else {
10541                conn.unstableCount = 1;
10542                conn.numUnstableIncs = 1;
10543            }
10544            cpr.connections.add(conn);
10545            r.conProviders.add(conn);
10546            startAssociationLocked(r.uid, r.processName, r.curProcState,
10547                    cpr.uid, cpr.name, cpr.info.processName);
10548            return conn;
10549        }
10550        cpr.addExternalProcessHandleLocked(externalProcessToken);
10551        return null;
10552    }
10553
10554    boolean decProviderCountLocked(ContentProviderConnection conn,
10555            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10556        if (conn != null) {
10557            cpr = conn.provider;
10558            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10559                    "Removing provider requested by "
10560                    + conn.client.processName + " from process "
10561                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10562                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10563            if (stable) {
10564                conn.stableCount--;
10565            } else {
10566                conn.unstableCount--;
10567            }
10568            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10569                cpr.connections.remove(conn);
10570                conn.client.conProviders.remove(conn);
10571                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10572                    // The client is more important than last activity -- note the time this
10573                    // is happening, so we keep the old provider process around a bit as last
10574                    // activity to avoid thrashing it.
10575                    if (cpr.proc != null) {
10576                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10577                    }
10578                }
10579                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10580                return true;
10581            }
10582            return false;
10583        }
10584        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10585        return false;
10586    }
10587
10588    private void checkTime(long startTime, String where) {
10589        long now = SystemClock.uptimeMillis();
10590        if ((now-startTime) > 50) {
10591            // If we are taking more than 50ms, log about it.
10592            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10593        }
10594    }
10595
10596    private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
10597            PROC_SPACE_TERM,
10598            PROC_SPACE_TERM|PROC_PARENS,
10599            PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
10600    };
10601
10602    private final long[] mProcessStateStatsLongs = new long[1];
10603
10604    boolean isProcessAliveLocked(ProcessRecord proc) {
10605        if (proc.procStatFile == null) {
10606            proc.procStatFile = "/proc/" + proc.pid + "/stat";
10607        }
10608        mProcessStateStatsLongs[0] = 0;
10609        if (!Process.readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
10610                mProcessStateStatsLongs, null)) {
10611            if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
10612            return false;
10613        }
10614        final long state = mProcessStateStatsLongs[0];
10615        if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
10616                + (char)state);
10617        return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
10618    }
10619
10620    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10621            String name, IBinder token, boolean stable, int userId) {
10622        ContentProviderRecord cpr;
10623        ContentProviderConnection conn = null;
10624        ProviderInfo cpi = null;
10625
10626        synchronized(this) {
10627            long startTime = SystemClock.uptimeMillis();
10628
10629            ProcessRecord r = null;
10630            if (caller != null) {
10631                r = getRecordForAppLocked(caller);
10632                if (r == null) {
10633                    throw new SecurityException(
10634                            "Unable to find app for caller " + caller
10635                          + " (pid=" + Binder.getCallingPid()
10636                          + ") when getting content provider " + name);
10637                }
10638            }
10639
10640            boolean checkCrossUser = true;
10641
10642            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10643
10644            // First check if this content provider has been published...
10645            cpr = mProviderMap.getProviderByName(name, userId);
10646            // If that didn't work, check if it exists for user 0 and then
10647            // verify that it's a singleton provider before using it.
10648            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10649                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10650                if (cpr != null) {
10651                    cpi = cpr.info;
10652                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10653                            cpi.name, cpi.flags)
10654                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10655                        userId = UserHandle.USER_SYSTEM;
10656                        checkCrossUser = false;
10657                    } else {
10658                        cpr = null;
10659                        cpi = null;
10660                    }
10661                }
10662            }
10663
10664            boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
10665            if (providerRunning) {
10666                cpi = cpr.info;
10667                String msg;
10668                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10669                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10670                        != null) {
10671                    throw new SecurityException(msg);
10672                }
10673                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10674
10675                if (r != null && cpr.canRunHere(r)) {
10676                    // This provider has been published or is in the process
10677                    // of being published...  but it is also allowed to run
10678                    // in the caller's process, so don't make a connection
10679                    // and just let the caller instantiate its own instance.
10680                    ContentProviderHolder holder = cpr.newHolder(null);
10681                    // don't give caller the provider object, it needs
10682                    // to make its own.
10683                    holder.provider = null;
10684                    return holder;
10685                }
10686
10687                final long origId = Binder.clearCallingIdentity();
10688
10689                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10690
10691                // In this case the provider instance already exists, so we can
10692                // return it right away.
10693                conn = incProviderCountLocked(r, cpr, token, stable);
10694                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10695                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10696                        // If this is a perceptible app accessing the provider,
10697                        // make sure to count it as being accessed and thus
10698                        // back up on the LRU list.  This is good because
10699                        // content providers are often expensive to start.
10700                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10701                        updateLruProcessLocked(cpr.proc, false, null);
10702                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10703                    }
10704                }
10705
10706                checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10707                final int verifiedAdj = cpr.proc.verifiedAdj;
10708                boolean success = updateOomAdjLocked(cpr.proc);
10709                // XXX things have changed so updateOomAdjLocked doesn't actually tell us
10710                // if the process has been successfully adjusted.  So to reduce races with
10711                // it, we will check whether the process still exists.  Note that this doesn't
10712                // completely get rid of races with LMK killing the process, but should make
10713                // them much smaller.
10714                if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
10715                    success = false;
10716                }
10717                maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10718                checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10719                if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10720                // NOTE: there is still a race here where a signal could be
10721                // pending on the process even though we managed to update its
10722                // adj level.  Not sure what to do about this, but at least
10723                // the race is now smaller.
10724                if (!success) {
10725                    // Uh oh...  it looks like the provider's process
10726                    // has been killed on us.  We need to wait for a new
10727                    // process to be started, and make sure its death
10728                    // doesn't kill our process.
10729                    Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10730                            + " is crashing; detaching " + r);
10731                    boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10732                    checkTime(startTime, "getContentProviderImpl: before appDied");
10733                    appDiedLocked(cpr.proc);
10734                    checkTime(startTime, "getContentProviderImpl: after appDied");
10735                    if (!lastRef) {
10736                        // This wasn't the last ref our process had on
10737                        // the provider...  we have now been killed, bail.
10738                        return null;
10739                    }
10740                    providerRunning = false;
10741                    conn = null;
10742                } else {
10743                    cpr.proc.verifiedAdj = cpr.proc.setAdj;
10744                }
10745
10746                Binder.restoreCallingIdentity(origId);
10747            }
10748
10749            if (!providerRunning) {
10750                try {
10751                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10752                    cpi = AppGlobals.getPackageManager().
10753                        resolveContentProvider(name,
10754                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10755                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10756                } catch (RemoteException ex) {
10757                }
10758                if (cpi == null) {
10759                    return null;
10760                }
10761                // If the provider is a singleton AND
10762                // (it's a call within the same user || the provider is a
10763                // privileged app)
10764                // Then allow connecting to the singleton provider
10765                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10766                        cpi.name, cpi.flags)
10767                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10768                if (singleton) {
10769                    userId = UserHandle.USER_SYSTEM;
10770                }
10771                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10772                checkTime(startTime, "getContentProviderImpl: got app info for user");
10773
10774                String msg;
10775                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10776                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10777                        != null) {
10778                    throw new SecurityException(msg);
10779                }
10780                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10781
10782                if (!mProcessesReady
10783                        && !cpi.processName.equals("system")) {
10784                    // If this content provider does not run in the system
10785                    // process, and the system is not yet ready to run other
10786                    // processes, then fail fast instead of hanging.
10787                    throw new IllegalArgumentException(
10788                            "Attempt to launch content provider before system ready");
10789                }
10790
10791                // Make sure that the user who owns this provider is running.  If not,
10792                // we don't want to allow it to run.
10793                if (!mUserController.isUserRunningLocked(userId, 0)) {
10794                    Slog.w(TAG, "Unable to launch app "
10795                            + cpi.applicationInfo.packageName + "/"
10796                            + cpi.applicationInfo.uid + " for provider "
10797                            + name + ": user " + userId + " is stopped");
10798                    return null;
10799                }
10800
10801                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10802                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10803                cpr = mProviderMap.getProviderByClass(comp, userId);
10804                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10805                final boolean firstClass = cpr == null;
10806                if (firstClass) {
10807                    final long ident = Binder.clearCallingIdentity();
10808
10809                    // If permissions need a review before any of the app components can run,
10810                    // we return no provider and launch a review activity if the calling app
10811                    // is in the foreground.
10812                    if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10813                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10814                            return null;
10815                        }
10816                    }
10817
10818                    try {
10819                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10820                        ApplicationInfo ai =
10821                            AppGlobals.getPackageManager().
10822                                getApplicationInfo(
10823                                        cpi.applicationInfo.packageName,
10824                                        STOCK_PM_FLAGS, userId);
10825                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10826                        if (ai == null) {
10827                            Slog.w(TAG, "No package info for content provider "
10828                                    + cpi.name);
10829                            return null;
10830                        }
10831                        ai = getAppInfoForUser(ai, userId);
10832                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10833                    } catch (RemoteException ex) {
10834                        // pm is in same process, this will never happen.
10835                    } finally {
10836                        Binder.restoreCallingIdentity(ident);
10837                    }
10838                }
10839
10840                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10841
10842                if (r != null && cpr.canRunHere(r)) {
10843                    // If this is a multiprocess provider, then just return its
10844                    // info and allow the caller to instantiate it.  Only do
10845                    // this if the provider is the same user as the caller's
10846                    // process, or can run as root (so can be in any process).
10847                    return cpr.newHolder(null);
10848                }
10849
10850                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10851                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10852                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10853
10854                // This is single process, and our app is now connecting to it.
10855                // See if we are already in the process of launching this
10856                // provider.
10857                final int N = mLaunchingProviders.size();
10858                int i;
10859                for (i = 0; i < N; i++) {
10860                    if (mLaunchingProviders.get(i) == cpr) {
10861                        break;
10862                    }
10863                }
10864
10865                // If the provider is not already being launched, then get it
10866                // started.
10867                if (i >= N) {
10868                    final long origId = Binder.clearCallingIdentity();
10869
10870                    try {
10871                        // Content provider is now in use, its package can't be stopped.
10872                        try {
10873                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10874                            AppGlobals.getPackageManager().setPackageStoppedState(
10875                                    cpr.appInfo.packageName, false, userId);
10876                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10877                        } catch (RemoteException e) {
10878                        } catch (IllegalArgumentException e) {
10879                            Slog.w(TAG, "Failed trying to unstop package "
10880                                    + cpr.appInfo.packageName + ": " + e);
10881                        }
10882
10883                        // Use existing process if already started
10884                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10885                        ProcessRecord proc = getProcessRecordLocked(
10886                                cpi.processName, cpr.appInfo.uid, false);
10887                        if (proc != null && proc.thread != null && !proc.killed) {
10888                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10889                                    "Installing in existing process " + proc);
10890                            if (!proc.pubProviders.containsKey(cpi.name)) {
10891                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10892                                proc.pubProviders.put(cpi.name, cpr);
10893                                try {
10894                                    proc.thread.scheduleInstallProvider(cpi);
10895                                } catch (RemoteException e) {
10896                                }
10897                            }
10898                        } else {
10899                            checkTime(startTime, "getContentProviderImpl: before start process");
10900                            proc = startProcessLocked(cpi.processName,
10901                                    cpr.appInfo, false, 0, "content provider",
10902                                    new ComponentName(cpi.applicationInfo.packageName,
10903                                            cpi.name), false, false, false);
10904                            checkTime(startTime, "getContentProviderImpl: after start process");
10905                            if (proc == null) {
10906                                Slog.w(TAG, "Unable to launch app "
10907                                        + cpi.applicationInfo.packageName + "/"
10908                                        + cpi.applicationInfo.uid + " for provider "
10909                                        + name + ": process is bad");
10910                                return null;
10911                            }
10912                        }
10913                        cpr.launchingApp = proc;
10914                        mLaunchingProviders.add(cpr);
10915                    } finally {
10916                        Binder.restoreCallingIdentity(origId);
10917                    }
10918                }
10919
10920                checkTime(startTime, "getContentProviderImpl: updating data structures");
10921
10922                // Make sure the provider is published (the same provider class
10923                // may be published under multiple names).
10924                if (firstClass) {
10925                    mProviderMap.putProviderByClass(comp, cpr);
10926                }
10927
10928                mProviderMap.putProviderByName(name, cpr);
10929                conn = incProviderCountLocked(r, cpr, token, stable);
10930                if (conn != null) {
10931                    conn.waiting = true;
10932                }
10933            }
10934            checkTime(startTime, "getContentProviderImpl: done!");
10935        }
10936
10937        // Wait for the provider to be published...
10938        synchronized (cpr) {
10939            while (cpr.provider == null) {
10940                if (cpr.launchingApp == null) {
10941                    Slog.w(TAG, "Unable to launch app "
10942                            + cpi.applicationInfo.packageName + "/"
10943                            + cpi.applicationInfo.uid + " for provider "
10944                            + name + ": launching app became null");
10945                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10946                            UserHandle.getUserId(cpi.applicationInfo.uid),
10947                            cpi.applicationInfo.packageName,
10948                            cpi.applicationInfo.uid, name);
10949                    return null;
10950                }
10951                try {
10952                    if (DEBUG_MU) Slog.v(TAG_MU,
10953                            "Waiting to start provider " + cpr
10954                            + " launchingApp=" + cpr.launchingApp);
10955                    if (conn != null) {
10956                        conn.waiting = true;
10957                    }
10958                    cpr.wait();
10959                } catch (InterruptedException ex) {
10960                } finally {
10961                    if (conn != null) {
10962                        conn.waiting = false;
10963                    }
10964                }
10965            }
10966        }
10967        return cpr != null ? cpr.newHolder(conn) : null;
10968    }
10969
10970    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10971            ProcessRecord r, final int userId) {
10972        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10973                cpi.packageName, userId)) {
10974
10975            final boolean callerForeground = r == null || r.setSchedGroup
10976                    != ProcessList.SCHED_GROUP_BACKGROUND;
10977
10978            // Show a permission review UI only for starting from a foreground app
10979            if (!callerForeground) {
10980                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
10981                        + cpi.packageName + " requires a permissions review");
10982                return false;
10983            }
10984
10985            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10986            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10987                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10988            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10989
10990            if (DEBUG_PERMISSIONS_REVIEW) {
10991                Slog.i(TAG, "u" + userId + " Launching permission review "
10992                        + "for package " + cpi.packageName);
10993            }
10994
10995            final UserHandle userHandle = new UserHandle(userId);
10996            mHandler.post(new Runnable() {
10997                @Override
10998                public void run() {
10999                    mContext.startActivityAsUser(intent, userHandle);
11000                }
11001            });
11002
11003            return false;
11004        }
11005
11006        return true;
11007    }
11008
11009    PackageManagerInternal getPackageManagerInternalLocked() {
11010        if (mPackageManagerInt == null) {
11011            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
11012        }
11013        return mPackageManagerInt;
11014    }
11015
11016    @Override
11017    public final ContentProviderHolder getContentProvider(
11018            IApplicationThread caller, String name, int userId, boolean stable) {
11019        enforceNotIsolatedCaller("getContentProvider");
11020        if (caller == null) {
11021            String msg = "null IApplicationThread when getting content provider "
11022                    + name;
11023            Slog.w(TAG, msg);
11024            throw new SecurityException(msg);
11025        }
11026        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
11027        // with cross-user grant.
11028        return getContentProviderImpl(caller, name, null, stable, userId);
11029    }
11030
11031    public ContentProviderHolder getContentProviderExternal(
11032            String name, int userId, IBinder token) {
11033        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11034            "Do not have permission in call getContentProviderExternal()");
11035        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
11036                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
11037        return getContentProviderExternalUnchecked(name, token, userId);
11038    }
11039
11040    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
11041            IBinder token, int userId) {
11042        return getContentProviderImpl(null, name, token, true, userId);
11043    }
11044
11045    /**
11046     * Drop a content provider from a ProcessRecord's bookkeeping
11047     */
11048    public void removeContentProvider(IBinder connection, boolean stable) {
11049        enforceNotIsolatedCaller("removeContentProvider");
11050        long ident = Binder.clearCallingIdentity();
11051        try {
11052            synchronized (this) {
11053                ContentProviderConnection conn;
11054                try {
11055                    conn = (ContentProviderConnection)connection;
11056                } catch (ClassCastException e) {
11057                    String msg ="removeContentProvider: " + connection
11058                            + " not a ContentProviderConnection";
11059                    Slog.w(TAG, msg);
11060                    throw new IllegalArgumentException(msg);
11061                }
11062                if (conn == null) {
11063                    throw new NullPointerException("connection is null");
11064                }
11065                if (decProviderCountLocked(conn, null, null, stable)) {
11066                    updateOomAdjLocked();
11067                }
11068            }
11069        } finally {
11070            Binder.restoreCallingIdentity(ident);
11071        }
11072    }
11073
11074    public void removeContentProviderExternal(String name, IBinder token) {
11075        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11076            "Do not have permission in call removeContentProviderExternal()");
11077        int userId = UserHandle.getCallingUserId();
11078        long ident = Binder.clearCallingIdentity();
11079        try {
11080            removeContentProviderExternalUnchecked(name, token, userId);
11081        } finally {
11082            Binder.restoreCallingIdentity(ident);
11083        }
11084    }
11085
11086    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11087        synchronized (this) {
11088            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11089            if(cpr == null) {
11090                //remove from mProvidersByClass
11091                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11092                return;
11093            }
11094
11095            //update content provider record entry info
11096            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11097            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11098            if (localCpr.hasExternalProcessHandles()) {
11099                if (localCpr.removeExternalProcessHandleLocked(token)) {
11100                    updateOomAdjLocked();
11101                } else {
11102                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11103                            + " with no external reference for token: "
11104                            + token + ".");
11105                }
11106            } else {
11107                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11108                        + " with no external references.");
11109            }
11110        }
11111    }
11112
11113    public final void publishContentProviders(IApplicationThread caller,
11114            List<ContentProviderHolder> providers) {
11115        if (providers == null) {
11116            return;
11117        }
11118
11119        enforceNotIsolatedCaller("publishContentProviders");
11120        synchronized (this) {
11121            final ProcessRecord r = getRecordForAppLocked(caller);
11122            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11123            if (r == null) {
11124                throw new SecurityException(
11125                        "Unable to find app for caller " + caller
11126                      + " (pid=" + Binder.getCallingPid()
11127                      + ") when publishing content providers");
11128            }
11129
11130            final long origId = Binder.clearCallingIdentity();
11131
11132            final int N = providers.size();
11133            for (int i = 0; i < N; i++) {
11134                ContentProviderHolder src = providers.get(i);
11135                if (src == null || src.info == null || src.provider == null) {
11136                    continue;
11137                }
11138                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11139                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11140                if (dst != null) {
11141                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11142                    mProviderMap.putProviderByClass(comp, dst);
11143                    String names[] = dst.info.authority.split(";");
11144                    for (int j = 0; j < names.length; j++) {
11145                        mProviderMap.putProviderByName(names[j], dst);
11146                    }
11147
11148                    int launchingCount = mLaunchingProviders.size();
11149                    int j;
11150                    boolean wasInLaunchingProviders = false;
11151                    for (j = 0; j < launchingCount; j++) {
11152                        if (mLaunchingProviders.get(j) == dst) {
11153                            mLaunchingProviders.remove(j);
11154                            wasInLaunchingProviders = true;
11155                            j--;
11156                            launchingCount--;
11157                        }
11158                    }
11159                    if (wasInLaunchingProviders) {
11160                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11161                    }
11162                    synchronized (dst) {
11163                        dst.provider = src.provider;
11164                        dst.proc = r;
11165                        dst.notifyAll();
11166                    }
11167                    updateOomAdjLocked(r);
11168                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11169                            src.info.authority);
11170                }
11171            }
11172
11173            Binder.restoreCallingIdentity(origId);
11174        }
11175    }
11176
11177    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11178        ContentProviderConnection conn;
11179        try {
11180            conn = (ContentProviderConnection)connection;
11181        } catch (ClassCastException e) {
11182            String msg ="refContentProvider: " + connection
11183                    + " not a ContentProviderConnection";
11184            Slog.w(TAG, msg);
11185            throw new IllegalArgumentException(msg);
11186        }
11187        if (conn == null) {
11188            throw new NullPointerException("connection is null");
11189        }
11190
11191        synchronized (this) {
11192            if (stable > 0) {
11193                conn.numStableIncs += stable;
11194            }
11195            stable = conn.stableCount + stable;
11196            if (stable < 0) {
11197                throw new IllegalStateException("stableCount < 0: " + stable);
11198            }
11199
11200            if (unstable > 0) {
11201                conn.numUnstableIncs += unstable;
11202            }
11203            unstable = conn.unstableCount + unstable;
11204            if (unstable < 0) {
11205                throw new IllegalStateException("unstableCount < 0: " + unstable);
11206            }
11207
11208            if ((stable+unstable) <= 0) {
11209                throw new IllegalStateException("ref counts can't go to zero here: stable="
11210                        + stable + " unstable=" + unstable);
11211            }
11212            conn.stableCount = stable;
11213            conn.unstableCount = unstable;
11214            return !conn.dead;
11215        }
11216    }
11217
11218    public void unstableProviderDied(IBinder connection) {
11219        ContentProviderConnection conn;
11220        try {
11221            conn = (ContentProviderConnection)connection;
11222        } catch (ClassCastException e) {
11223            String msg ="refContentProvider: " + connection
11224                    + " not a ContentProviderConnection";
11225            Slog.w(TAG, msg);
11226            throw new IllegalArgumentException(msg);
11227        }
11228        if (conn == null) {
11229            throw new NullPointerException("connection is null");
11230        }
11231
11232        // Safely retrieve the content provider associated with the connection.
11233        IContentProvider provider;
11234        synchronized (this) {
11235            provider = conn.provider.provider;
11236        }
11237
11238        if (provider == null) {
11239            // Um, yeah, we're way ahead of you.
11240            return;
11241        }
11242
11243        // Make sure the caller is being honest with us.
11244        if (provider.asBinder().pingBinder()) {
11245            // Er, no, still looks good to us.
11246            synchronized (this) {
11247                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11248                        + " says " + conn + " died, but we don't agree");
11249                return;
11250            }
11251        }
11252
11253        // Well look at that!  It's dead!
11254        synchronized (this) {
11255            if (conn.provider.provider != provider) {
11256                // But something changed...  good enough.
11257                return;
11258            }
11259
11260            ProcessRecord proc = conn.provider.proc;
11261            if (proc == null || proc.thread == null) {
11262                // Seems like the process is already cleaned up.
11263                return;
11264            }
11265
11266            // As far as we're concerned, this is just like receiving a
11267            // death notification...  just a bit prematurely.
11268            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11269                    + ") early provider death");
11270            final long ident = Binder.clearCallingIdentity();
11271            try {
11272                appDiedLocked(proc);
11273            } finally {
11274                Binder.restoreCallingIdentity(ident);
11275            }
11276        }
11277    }
11278
11279    @Override
11280    public void appNotRespondingViaProvider(IBinder connection) {
11281        enforceCallingPermission(
11282                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11283
11284        final ContentProviderConnection conn = (ContentProviderConnection) connection;
11285        if (conn == null) {
11286            Slog.w(TAG, "ContentProviderConnection is null");
11287            return;
11288        }
11289
11290        final ProcessRecord host = conn.provider.proc;
11291        if (host == null) {
11292            Slog.w(TAG, "Failed to find hosting ProcessRecord");
11293            return;
11294        }
11295
11296        mHandler.post(new Runnable() {
11297            @Override
11298            public void run() {
11299                mAppErrors.appNotResponding(host, null, null, false,
11300                        "ContentProvider not responding");
11301            }
11302        });
11303    }
11304
11305    public final void installSystemProviders() {
11306        List<ProviderInfo> providers;
11307        synchronized (this) {
11308            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11309            providers = generateApplicationProvidersLocked(app);
11310            if (providers != null) {
11311                for (int i=providers.size()-1; i>=0; i--) {
11312                    ProviderInfo pi = (ProviderInfo)providers.get(i);
11313                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11314                        Slog.w(TAG, "Not installing system proc provider " + pi.name
11315                                + ": not system .apk");
11316                        providers.remove(i);
11317                    }
11318                }
11319            }
11320        }
11321        if (providers != null) {
11322            mSystemThread.installSystemProviders(providers);
11323        }
11324
11325        mCoreSettingsObserver = new CoreSettingsObserver(this);
11326        mFontScaleSettingObserver = new FontScaleSettingObserver();
11327
11328        //mUsageStatsService.monitorPackages();
11329    }
11330
11331    private void startPersistentApps(int matchFlags) {
11332        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11333
11334        synchronized (this) {
11335            try {
11336                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11337                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11338                for (ApplicationInfo app : apps) {
11339                    if (!"android".equals(app.packageName)) {
11340                        addAppLocked(app, false, null /* ABI override */);
11341                    }
11342                }
11343            } catch (RemoteException ex) {
11344            }
11345        }
11346    }
11347
11348    /**
11349     * When a user is unlocked, we need to install encryption-unaware providers
11350     * belonging to any running apps.
11351     */
11352    private void installEncryptionUnawareProviders(int userId) {
11353        // We're only interested in providers that are encryption unaware, and
11354        // we don't care about uninstalled apps, since there's no way they're
11355        // running at this point.
11356        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11357
11358        synchronized (this) {
11359            final int NP = mProcessNames.getMap().size();
11360            for (int ip = 0; ip < NP; ip++) {
11361                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11362                final int NA = apps.size();
11363                for (int ia = 0; ia < NA; ia++) {
11364                    final ProcessRecord app = apps.valueAt(ia);
11365                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11366
11367                    final int NG = app.pkgList.size();
11368                    for (int ig = 0; ig < NG; ig++) {
11369                        try {
11370                            final String pkgName = app.pkgList.keyAt(ig);
11371                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11372                                    .getPackageInfo(pkgName, matchFlags, userId);
11373                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11374                                for (ProviderInfo pi : pkgInfo.providers) {
11375                                    // TODO: keep in sync with generateApplicationProvidersLocked
11376                                    final boolean processMatch = Objects.equals(pi.processName,
11377                                            app.processName) || pi.multiprocess;
11378                                    final boolean userMatch = isSingleton(pi.processName,
11379                                            pi.applicationInfo, pi.name, pi.flags)
11380                                                    ? (app.userId == UserHandle.USER_SYSTEM) : true;
11381                                    if (processMatch && userMatch) {
11382                                        Log.v(TAG, "Installing " + pi);
11383                                        app.thread.scheduleInstallProvider(pi);
11384                                    } else {
11385                                        Log.v(TAG, "Skipping " + pi);
11386                                    }
11387                                }
11388                            }
11389                        } catch (RemoteException ignored) {
11390                        }
11391                    }
11392                }
11393            }
11394        }
11395    }
11396
11397    /**
11398     * Allows apps to retrieve the MIME type of a URI.
11399     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11400     * users, then it does not need permission to access the ContentProvider.
11401     * Either, it needs cross-user uri grants.
11402     *
11403     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11404     *
11405     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11406     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11407     */
11408    public String getProviderMimeType(Uri uri, int userId) {
11409        enforceNotIsolatedCaller("getProviderMimeType");
11410        final String name = uri.getAuthority();
11411        int callingUid = Binder.getCallingUid();
11412        int callingPid = Binder.getCallingPid();
11413        long ident = 0;
11414        boolean clearedIdentity = false;
11415        synchronized (this) {
11416            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11417        }
11418        if (canClearIdentity(callingPid, callingUid, userId)) {
11419            clearedIdentity = true;
11420            ident = Binder.clearCallingIdentity();
11421        }
11422        ContentProviderHolder holder = null;
11423        try {
11424            holder = getContentProviderExternalUnchecked(name, null, userId);
11425            if (holder != null) {
11426                return holder.provider.getType(uri);
11427            }
11428        } catch (RemoteException e) {
11429            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11430            return null;
11431        } catch (Exception e) {
11432            Log.w(TAG, "Exception while determining type of " + uri, e);
11433            return null;
11434        } finally {
11435            // We need to clear the identity to call removeContentProviderExternalUnchecked
11436            if (!clearedIdentity) {
11437                ident = Binder.clearCallingIdentity();
11438            }
11439            try {
11440                if (holder != null) {
11441                    removeContentProviderExternalUnchecked(name, null, userId);
11442                }
11443            } finally {
11444                Binder.restoreCallingIdentity(ident);
11445            }
11446        }
11447
11448        return null;
11449    }
11450
11451    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11452        if (UserHandle.getUserId(callingUid) == userId) {
11453            return true;
11454        }
11455        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11456                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11457                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11458                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11459                return true;
11460        }
11461        return false;
11462    }
11463
11464    // =========================================================
11465    // GLOBAL MANAGEMENT
11466    // =========================================================
11467
11468    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11469            boolean isolated, int isolatedUid) {
11470        String proc = customProcess != null ? customProcess : info.processName;
11471        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11472        final int userId = UserHandle.getUserId(info.uid);
11473        int uid = info.uid;
11474        if (isolated) {
11475            if (isolatedUid == 0) {
11476                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11477                while (true) {
11478                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11479                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11480                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11481                    }
11482                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11483                    mNextIsolatedProcessUid++;
11484                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11485                        // No process for this uid, use it.
11486                        break;
11487                    }
11488                    stepsLeft--;
11489                    if (stepsLeft <= 0) {
11490                        return null;
11491                    }
11492                }
11493            } else {
11494                // Special case for startIsolatedProcess (internal only), where
11495                // the uid of the isolated process is specified by the caller.
11496                uid = isolatedUid;
11497            }
11498
11499            // Register the isolated UID with this application so BatteryStats knows to
11500            // attribute resource usage to the application.
11501            //
11502            // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
11503            // about the process state of the isolated UID *before* it is registered with the
11504            // owning application.
11505            mBatteryStatsService.addIsolatedUid(uid, info.uid);
11506        }
11507        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11508        if (!mBooted && !mBooting
11509                && userId == UserHandle.USER_SYSTEM
11510                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11511            r.persistent = true;
11512        }
11513        addProcessNameLocked(r);
11514        return r;
11515    }
11516
11517    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11518            String abiOverride) {
11519        ProcessRecord app;
11520        if (!isolated) {
11521            app = getProcessRecordLocked(info.processName, info.uid, true);
11522        } else {
11523            app = null;
11524        }
11525
11526        if (app == null) {
11527            app = newProcessRecordLocked(info, null, isolated, 0);
11528            updateLruProcessLocked(app, false, null);
11529            updateOomAdjLocked();
11530        }
11531
11532        // This package really, really can not be stopped.
11533        try {
11534            AppGlobals.getPackageManager().setPackageStoppedState(
11535                    info.packageName, false, UserHandle.getUserId(app.uid));
11536        } catch (RemoteException e) {
11537        } catch (IllegalArgumentException e) {
11538            Slog.w(TAG, "Failed trying to unstop package "
11539                    + info.packageName + ": " + e);
11540        }
11541
11542        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11543            app.persistent = true;
11544            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11545        }
11546        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11547            mPersistentStartingProcesses.add(app);
11548            startProcessLocked(app, "added application", app.processName, abiOverride,
11549                    null /* entryPoint */, null /* entryPointArgs */);
11550        }
11551
11552        return app;
11553    }
11554
11555    public void unhandledBack() {
11556        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11557                "unhandledBack()");
11558
11559        synchronized(this) {
11560            final long origId = Binder.clearCallingIdentity();
11561            try {
11562                getFocusedStack().unhandledBackLocked();
11563            } finally {
11564                Binder.restoreCallingIdentity(origId);
11565            }
11566        }
11567    }
11568
11569    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11570        enforceNotIsolatedCaller("openContentUri");
11571        final int userId = UserHandle.getCallingUserId();
11572        String name = uri.getAuthority();
11573        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11574        ParcelFileDescriptor pfd = null;
11575        if (cph != null) {
11576            // We record the binder invoker's uid in thread-local storage before
11577            // going to the content provider to open the file.  Later, in the code
11578            // that handles all permissions checks, we look for this uid and use
11579            // that rather than the Activity Manager's own uid.  The effect is that
11580            // we do the check against the caller's permissions even though it looks
11581            // to the content provider like the Activity Manager itself is making
11582            // the request.
11583            Binder token = new Binder();
11584            sCallerIdentity.set(new Identity(
11585                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11586            try {
11587                pfd = cph.provider.openFile(null, uri, "r", null, token);
11588            } catch (FileNotFoundException e) {
11589                // do nothing; pfd will be returned null
11590            } finally {
11591                // Ensure that whatever happens, we clean up the identity state
11592                sCallerIdentity.remove();
11593                // Ensure we're done with the provider.
11594                removeContentProviderExternalUnchecked(name, null, userId);
11595            }
11596        } else {
11597            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11598        }
11599        return pfd;
11600    }
11601
11602    // Actually is sleeping or shutting down or whatever else in the future
11603    // is an inactive state.
11604    boolean isSleepingOrShuttingDownLocked() {
11605        return isSleepingLocked() || mShuttingDown;
11606    }
11607
11608    boolean isShuttingDownLocked() {
11609        return mShuttingDown;
11610    }
11611
11612    boolean isSleepingLocked() {
11613        return mSleeping;
11614    }
11615
11616    void onWakefulnessChanged(int wakefulness) {
11617        synchronized(this) {
11618            mWakefulness = wakefulness;
11619            updateSleepIfNeededLocked();
11620        }
11621    }
11622
11623    void finishRunningVoiceLocked() {
11624        if (mRunningVoice != null) {
11625            mRunningVoice = null;
11626            mVoiceWakeLock.release();
11627            updateSleepIfNeededLocked();
11628        }
11629    }
11630
11631    void startTimeTrackingFocusedActivityLocked() {
11632        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11633            mCurAppTimeTracker.start(mFocusedActivity.packageName);
11634        }
11635    }
11636
11637    void updateSleepIfNeededLocked() {
11638        if (mSleeping && !shouldSleepLocked()) {
11639            mSleeping = false;
11640            startTimeTrackingFocusedActivityLocked();
11641            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11642            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11643            updateOomAdjLocked();
11644        } else if (!mSleeping && shouldSleepLocked()) {
11645            mSleeping = true;
11646            if (mCurAppTimeTracker != null) {
11647                mCurAppTimeTracker.stop();
11648            }
11649            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11650            mStackSupervisor.goingToSleepLocked();
11651            updateOomAdjLocked();
11652
11653            // Initialize the wake times of all processes.
11654            checkExcessivePowerUsageLocked(false);
11655            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11656            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11657            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11658        }
11659    }
11660
11661    private boolean shouldSleepLocked() {
11662        // Resume applications while running a voice interactor.
11663        if (mRunningVoice != null) {
11664            return false;
11665        }
11666
11667        // TODO: Transform the lock screen state into a sleep token instead.
11668        switch (mWakefulness) {
11669            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11670            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11671            case PowerManagerInternal.WAKEFULNESS_DOZING:
11672                // Pause applications whenever the lock screen is shown or any sleep
11673                // tokens have been acquired.
11674                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11675            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11676            default:
11677                // If we're asleep then pause applications unconditionally.
11678                return true;
11679        }
11680    }
11681
11682    /** Pokes the task persister. */
11683    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11684        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11685    }
11686
11687    /** Notifies all listeners when the task stack has changed. */
11688    void notifyTaskStackChangedLocked() {
11689        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11690        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11691        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11692        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11693    }
11694
11695    /** Notifies all listeners when an Activity is pinned. */
11696    void notifyActivityPinnedLocked() {
11697        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11698        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11699    }
11700
11701    /**
11702     * Notifies all listeners when an attempt was made to start an an activity that is already
11703     * running in the pinned stack and the activity was not actually started, but the task is
11704     * either brought to the front or a new Intent is delivered to it.
11705     */
11706    void notifyPinnedActivityRestartAttemptLocked() {
11707        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11708        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11709    }
11710
11711    /** Notifies all listeners when the pinned stack animation ends. */
11712    @Override
11713    public void notifyPinnedStackAnimationEnded() {
11714        synchronized (this) {
11715            mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11716            mHandler.obtainMessage(
11717                    NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11718        }
11719    }
11720
11721    @Override
11722    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11723        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11724    }
11725
11726    @Override
11727    public boolean shutdown(int timeout) {
11728        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11729                != PackageManager.PERMISSION_GRANTED) {
11730            throw new SecurityException("Requires permission "
11731                    + android.Manifest.permission.SHUTDOWN);
11732        }
11733
11734        boolean timedout = false;
11735
11736        synchronized(this) {
11737            mShuttingDown = true;
11738            updateEventDispatchingLocked();
11739            timedout = mStackSupervisor.shutdownLocked(timeout);
11740        }
11741
11742        mAppOpsService.shutdown();
11743        if (mUsageStatsService != null) {
11744            mUsageStatsService.prepareShutdown();
11745        }
11746        mBatteryStatsService.shutdown();
11747        synchronized (this) {
11748            mProcessStats.shutdownLocked();
11749            notifyTaskPersisterLocked(null, true);
11750        }
11751
11752        return timedout;
11753    }
11754
11755    public final void activitySlept(IBinder token) {
11756        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11757
11758        final long origId = Binder.clearCallingIdentity();
11759
11760        synchronized (this) {
11761            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11762            if (r != null) {
11763                mStackSupervisor.activitySleptLocked(r);
11764            }
11765        }
11766
11767        Binder.restoreCallingIdentity(origId);
11768    }
11769
11770    private String lockScreenShownToString() {
11771        switch (mLockScreenShown) {
11772            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11773            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11774            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11775            default: return "Unknown=" + mLockScreenShown;
11776        }
11777    }
11778
11779    void logLockScreen(String msg) {
11780        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11781                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11782                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11783                + " mSleeping=" + mSleeping);
11784    }
11785
11786    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11787        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11788        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11789        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11790            boolean wasRunningVoice = mRunningVoice != null;
11791            mRunningVoice = session;
11792            if (!wasRunningVoice) {
11793                mVoiceWakeLock.acquire();
11794                updateSleepIfNeededLocked();
11795            }
11796        }
11797    }
11798
11799    private void updateEventDispatchingLocked() {
11800        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11801    }
11802
11803    public void setLockScreenShown(boolean showing, boolean occluded) {
11804        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11805                != PackageManager.PERMISSION_GRANTED) {
11806            throw new SecurityException("Requires permission "
11807                    + android.Manifest.permission.DEVICE_POWER);
11808        }
11809
11810        synchronized(this) {
11811            long ident = Binder.clearCallingIdentity();
11812            try {
11813                if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
11814                mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11815                if (showing && occluded) {
11816                    // The lock screen is currently showing, but is occluded by a window that can
11817                    // show on top of the lock screen. In this can we want to dismiss the docked
11818                    // stack since it will be complicated/risky to try to put the activity on top
11819                    // of the lock screen in the right fullscreen configuration.
11820                    mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
11821                            mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
11822                }
11823
11824                updateSleepIfNeededLocked();
11825            } finally {
11826                Binder.restoreCallingIdentity(ident);
11827            }
11828        }
11829    }
11830
11831    @Override
11832    public void notifyLockedProfile(@UserIdInt int userId) {
11833        try {
11834            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11835                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11836            }
11837        } catch (RemoteException ex) {
11838            throw new SecurityException("Fail to check is caller a privileged app", ex);
11839        }
11840
11841        synchronized (this) {
11842            if (mStackSupervisor.isUserLockedProfile(userId)) {
11843                final long ident = Binder.clearCallingIdentity();
11844                try {
11845                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11846
11847                    // Drop locked freeform tasks out into the fullscreen stack.
11848                    // TODO: Redact the tasks in place. It's much better to keep them on the screen
11849                    //       where they were before, but in an obscured state.
11850                    mStackSupervisor.moveProfileTasksFromFreeformToFullscreenStackLocked(userId);
11851
11852                    if (mUserController.isLockScreenDisabled(currentUserId)) {
11853                        // If there is no device lock, we will show the profile's credential page.
11854                        mActivityStarter.showConfirmDeviceCredential(userId);
11855                    } else {
11856                        // Showing launcher to avoid user entering credential twice.
11857                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11858                    }
11859                } finally {
11860                    Binder.restoreCallingIdentity(ident);
11861                }
11862            }
11863        }
11864    }
11865
11866    @Override
11867    public void startConfirmDeviceCredentialIntent(Intent intent) {
11868        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11869        synchronized (this) {
11870            final long ident = Binder.clearCallingIdentity();
11871            try {
11872                mActivityStarter.startConfirmCredentialIntent(intent);
11873            } finally {
11874                Binder.restoreCallingIdentity(ident);
11875            }
11876        }
11877    }
11878
11879    @Override
11880    public void stopAppSwitches() {
11881        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11882                != PackageManager.PERMISSION_GRANTED) {
11883            throw new SecurityException("viewquires permission "
11884                    + android.Manifest.permission.STOP_APP_SWITCHES);
11885        }
11886
11887        synchronized(this) {
11888            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11889                    + APP_SWITCH_DELAY_TIME;
11890            mDidAppSwitch = false;
11891            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11892            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11893            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11894        }
11895    }
11896
11897    public void resumeAppSwitches() {
11898        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11899                != PackageManager.PERMISSION_GRANTED) {
11900            throw new SecurityException("Requires permission "
11901                    + android.Manifest.permission.STOP_APP_SWITCHES);
11902        }
11903
11904        synchronized(this) {
11905            // Note that we don't execute any pending app switches... we will
11906            // let those wait until either the timeout, or the next start
11907            // activity request.
11908            mAppSwitchesAllowedTime = 0;
11909        }
11910    }
11911
11912    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11913            int callingPid, int callingUid, String name) {
11914        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11915            return true;
11916        }
11917
11918        int perm = checkComponentPermission(
11919                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11920                sourceUid, -1, true);
11921        if (perm == PackageManager.PERMISSION_GRANTED) {
11922            return true;
11923        }
11924
11925        // If the actual IPC caller is different from the logical source, then
11926        // also see if they are allowed to control app switches.
11927        if (callingUid != -1 && callingUid != sourceUid) {
11928            perm = checkComponentPermission(
11929                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11930                    callingUid, -1, true);
11931            if (perm == PackageManager.PERMISSION_GRANTED) {
11932                return true;
11933            }
11934        }
11935
11936        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11937        return false;
11938    }
11939
11940    public void setDebugApp(String packageName, boolean waitForDebugger,
11941            boolean persistent) {
11942        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11943                "setDebugApp()");
11944
11945        long ident = Binder.clearCallingIdentity();
11946        try {
11947            // Note that this is not really thread safe if there are multiple
11948            // callers into it at the same time, but that's not a situation we
11949            // care about.
11950            if (persistent) {
11951                final ContentResolver resolver = mContext.getContentResolver();
11952                Settings.Global.putString(
11953                    resolver, Settings.Global.DEBUG_APP,
11954                    packageName);
11955                Settings.Global.putInt(
11956                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11957                    waitForDebugger ? 1 : 0);
11958            }
11959
11960            synchronized (this) {
11961                if (!persistent) {
11962                    mOrigDebugApp = mDebugApp;
11963                    mOrigWaitForDebugger = mWaitForDebugger;
11964                }
11965                mDebugApp = packageName;
11966                mWaitForDebugger = waitForDebugger;
11967                mDebugTransient = !persistent;
11968                if (packageName != null) {
11969                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11970                            false, UserHandle.USER_ALL, "set debug app");
11971                }
11972            }
11973        } finally {
11974            Binder.restoreCallingIdentity(ident);
11975        }
11976    }
11977
11978    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11979        synchronized (this) {
11980            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11981            if (!isDebuggable) {
11982                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11983                    throw new SecurityException("Process not debuggable: " + app.packageName);
11984                }
11985            }
11986
11987            mTrackAllocationApp = processName;
11988        }
11989    }
11990
11991    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11992        synchronized (this) {
11993            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11994            if (!isDebuggable) {
11995                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11996                    throw new SecurityException("Process not debuggable: " + app.packageName);
11997                }
11998            }
11999            mProfileApp = processName;
12000            mProfileFile = profilerInfo.profileFile;
12001            if (mProfileFd != null) {
12002                try {
12003                    mProfileFd.close();
12004                } catch (IOException e) {
12005                }
12006                mProfileFd = null;
12007            }
12008            mProfileFd = profilerInfo.profileFd;
12009            mSamplingInterval = profilerInfo.samplingInterval;
12010            mAutoStopProfiler = profilerInfo.autoStopProfiler;
12011            mProfileType = 0;
12012        }
12013    }
12014
12015    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
12016        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12017        if (!isDebuggable) {
12018            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12019                throw new SecurityException("Process not debuggable: " + app.packageName);
12020            }
12021        }
12022        mNativeDebuggingApp = processName;
12023    }
12024
12025    @Override
12026    public void setAlwaysFinish(boolean enabled) {
12027        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
12028                "setAlwaysFinish()");
12029
12030        long ident = Binder.clearCallingIdentity();
12031        try {
12032            Settings.Global.putInt(
12033                    mContext.getContentResolver(),
12034                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
12035
12036            synchronized (this) {
12037                mAlwaysFinishActivities = enabled;
12038            }
12039        } finally {
12040            Binder.restoreCallingIdentity(ident);
12041        }
12042    }
12043
12044    @Override
12045    public void setLenientBackgroundCheck(boolean enabled) {
12046        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
12047                "setLenientBackgroundCheck()");
12048
12049        long ident = Binder.clearCallingIdentity();
12050        try {
12051            Settings.Global.putInt(
12052                    mContext.getContentResolver(),
12053                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
12054
12055            synchronized (this) {
12056                mLenientBackgroundCheck = enabled;
12057            }
12058        } finally {
12059            Binder.restoreCallingIdentity(ident);
12060        }
12061    }
12062
12063    @Override
12064    public void setActivityController(IActivityController controller, boolean imAMonkey) {
12065        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12066                "setActivityController()");
12067        synchronized (this) {
12068            mController = controller;
12069            mControllerIsAMonkey = imAMonkey;
12070            Watchdog.getInstance().setActivityController(controller);
12071        }
12072    }
12073
12074    @Override
12075    public void setUserIsMonkey(boolean userIsMonkey) {
12076        synchronized (this) {
12077            synchronized (mPidsSelfLocked) {
12078                final int callingPid = Binder.getCallingPid();
12079                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
12080                if (precessRecord == null) {
12081                    throw new SecurityException("Unknown process: " + callingPid);
12082                }
12083                if (precessRecord.instrumentationUiAutomationConnection  == null) {
12084                    throw new SecurityException("Only an instrumentation process "
12085                            + "with a UiAutomation can call setUserIsMonkey");
12086                }
12087            }
12088            mUserIsMonkey = userIsMonkey;
12089        }
12090    }
12091
12092    @Override
12093    public boolean isUserAMonkey() {
12094        synchronized (this) {
12095            // If there is a controller also implies the user is a monkey.
12096            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12097        }
12098    }
12099
12100    public void requestBugReport(int bugreportType) {
12101        String service = null;
12102        switch (bugreportType) {
12103            case ActivityManager.BUGREPORT_OPTION_FULL:
12104                service = "bugreport";
12105                break;
12106            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12107                service = "bugreportplus";
12108                break;
12109            case ActivityManager.BUGREPORT_OPTION_REMOTE:
12110                service = "bugreportremote";
12111                break;
12112            case ActivityManager.BUGREPORT_OPTION_WEAR:
12113                service = "bugreportwear";
12114                break;
12115        }
12116        if (service == null) {
12117            throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12118                    + bugreportType);
12119        }
12120        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12121        SystemProperties.set("ctl.start", service);
12122    }
12123
12124    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12125        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12126    }
12127
12128    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12129        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
12130            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12131        }
12132        return KEY_DISPATCHING_TIMEOUT;
12133    }
12134
12135    @Override
12136    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12137        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12138                != PackageManager.PERMISSION_GRANTED) {
12139            throw new SecurityException("Requires permission "
12140                    + android.Manifest.permission.FILTER_EVENTS);
12141        }
12142        ProcessRecord proc;
12143        long timeout;
12144        synchronized (this) {
12145            synchronized (mPidsSelfLocked) {
12146                proc = mPidsSelfLocked.get(pid);
12147            }
12148            timeout = getInputDispatchingTimeoutLocked(proc);
12149        }
12150
12151        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12152            return -1;
12153        }
12154
12155        return timeout;
12156    }
12157
12158    /**
12159     * Handle input dispatching timeouts.
12160     * Returns whether input dispatching should be aborted or not.
12161     */
12162    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12163            final ActivityRecord activity, final ActivityRecord parent,
12164            final boolean aboveSystem, String reason) {
12165        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12166                != PackageManager.PERMISSION_GRANTED) {
12167            throw new SecurityException("Requires permission "
12168                    + android.Manifest.permission.FILTER_EVENTS);
12169        }
12170
12171        final String annotation;
12172        if (reason == null) {
12173            annotation = "Input dispatching timed out";
12174        } else {
12175            annotation = "Input dispatching timed out (" + reason + ")";
12176        }
12177
12178        if (proc != null) {
12179            synchronized (this) {
12180                if (proc.debugging) {
12181                    return false;
12182                }
12183
12184                if (mDidDexOpt) {
12185                    // Give more time since we were dexopting.
12186                    mDidDexOpt = false;
12187                    return false;
12188                }
12189
12190                if (proc.instrumentationClass != null) {
12191                    Bundle info = new Bundle();
12192                    info.putString("shortMsg", "keyDispatchingTimedOut");
12193                    info.putString("longMsg", annotation);
12194                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12195                    return true;
12196                }
12197            }
12198            mHandler.post(new Runnable() {
12199                @Override
12200                public void run() {
12201                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12202                }
12203            });
12204        }
12205
12206        return true;
12207    }
12208
12209    @Override
12210    public Bundle getAssistContextExtras(int requestType) {
12211        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12212                null, null, true /* focused */, true /* newSessionId */,
12213                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
12214        if (pae == null) {
12215            return null;
12216        }
12217        synchronized (pae) {
12218            while (!pae.haveResult) {
12219                try {
12220                    pae.wait();
12221                } catch (InterruptedException e) {
12222                }
12223            }
12224        }
12225        synchronized (this) {
12226            buildAssistBundleLocked(pae, pae.result);
12227            mPendingAssistExtras.remove(pae);
12228            mUiHandler.removeCallbacks(pae);
12229        }
12230        return pae.extras;
12231    }
12232
12233    @Override
12234    public boolean isAssistDataAllowedOnCurrentActivity() {
12235        int userId;
12236        synchronized (this) {
12237            userId = mUserController.getCurrentUserIdLocked();
12238            ActivityRecord activity = getFocusedStack().topActivity();
12239            if (activity == null) {
12240                return false;
12241            }
12242            userId = activity.userId;
12243        }
12244        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12245                Context.DEVICE_POLICY_SERVICE);
12246        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12247    }
12248
12249    @Override
12250    public boolean showAssistFromActivity(IBinder token, Bundle args) {
12251        long ident = Binder.clearCallingIdentity();
12252        try {
12253            synchronized (this) {
12254                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12255                ActivityRecord top = getFocusedStack().topActivity();
12256                if (top != caller) {
12257                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12258                            + " is not current top " + top);
12259                    return false;
12260                }
12261                if (!top.nowVisible) {
12262                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12263                            + " is not visible");
12264                    return false;
12265                }
12266            }
12267            AssistUtils utils = new AssistUtils(mContext);
12268            return utils.showSessionForActiveService(args,
12269                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
12270        } finally {
12271            Binder.restoreCallingIdentity(ident);
12272        }
12273    }
12274
12275    @Override
12276    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12277            Bundle receiverExtras,
12278            IBinder activityToken, boolean focused, boolean newSessionId) {
12279        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12280                activityToken, focused, newSessionId,
12281                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
12282                != null;
12283    }
12284
12285    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12286            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12287            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12288        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12289                "enqueueAssistContext()");
12290        synchronized (this) {
12291            ActivityRecord activity = getFocusedStack().topActivity();
12292            if (activity == null) {
12293                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12294                return null;
12295            }
12296            if (activity.app == null || activity.app.thread == null) {
12297                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12298                return null;
12299            }
12300            if (focused) {
12301                if (activityToken != null) {
12302                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12303                    if (activity != caller) {
12304                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12305                                + " is not current top " + activity);
12306                        return null;
12307                    }
12308                }
12309            } else {
12310                activity = ActivityRecord.forTokenLocked(activityToken);
12311                if (activity == null) {
12312                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12313                            + " couldn't be found");
12314                    return null;
12315                }
12316            }
12317
12318            PendingAssistExtras pae;
12319            Bundle extras = new Bundle();
12320            if (args != null) {
12321                extras.putAll(args);
12322            }
12323            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12324            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12325            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12326                    userHandle);
12327            // Increment the sessionId if necessary
12328            if (newSessionId) {
12329                mViSessionId++;
12330            }
12331            try {
12332                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12333                        requestType, mViSessionId);
12334                mPendingAssistExtras.add(pae);
12335                mUiHandler.postDelayed(pae, timeout);
12336            } catch (RemoteException e) {
12337                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12338                return null;
12339            }
12340            return pae;
12341        }
12342    }
12343
12344    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12345        IResultReceiver receiver;
12346        synchronized (this) {
12347            mPendingAssistExtras.remove(pae);
12348            receiver = pae.receiver;
12349        }
12350        if (receiver != null) {
12351            // Caller wants result sent back to them.
12352            Bundle sendBundle = new Bundle();
12353            // At least return the receiver extras
12354            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12355                    pae.receiverExtras);
12356            try {
12357                pae.receiver.send(0, sendBundle);
12358            } catch (RemoteException e) {
12359            }
12360        }
12361    }
12362
12363    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12364        if (result != null) {
12365            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12366        }
12367        if (pae.hint != null) {
12368            pae.extras.putBoolean(pae.hint, true);
12369        }
12370    }
12371
12372    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12373            AssistContent content, Uri referrer) {
12374        PendingAssistExtras pae = (PendingAssistExtras)token;
12375        synchronized (pae) {
12376            pae.result = extras;
12377            pae.structure = structure;
12378            pae.content = content;
12379            if (referrer != null) {
12380                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12381            }
12382            pae.haveResult = true;
12383            pae.notifyAll();
12384            if (pae.intent == null && pae.receiver == null) {
12385                // Caller is just waiting for the result.
12386                return;
12387            }
12388        }
12389
12390        // We are now ready to launch the assist activity.
12391        IResultReceiver sendReceiver = null;
12392        Bundle sendBundle = null;
12393        synchronized (this) {
12394            buildAssistBundleLocked(pae, extras);
12395            boolean exists = mPendingAssistExtras.remove(pae);
12396            mUiHandler.removeCallbacks(pae);
12397            if (!exists) {
12398                // Timed out.
12399                return;
12400            }
12401            if ((sendReceiver=pae.receiver) != null) {
12402                // Caller wants result sent back to them.
12403                sendBundle = new Bundle();
12404                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12405                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12406                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12407                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12408                        pae.receiverExtras);
12409            }
12410        }
12411        if (sendReceiver != null) {
12412            try {
12413                sendReceiver.send(0, sendBundle);
12414            } catch (RemoteException e) {
12415            }
12416            return;
12417        }
12418
12419        long ident = Binder.clearCallingIdentity();
12420        try {
12421            pae.intent.replaceExtras(pae.extras);
12422            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12423                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12424                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12425            closeSystemDialogs("assist");
12426            try {
12427                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12428            } catch (ActivityNotFoundException e) {
12429                Slog.w(TAG, "No activity to handle assist action.", e);
12430            }
12431        } finally {
12432            Binder.restoreCallingIdentity(ident);
12433        }
12434    }
12435
12436    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12437            Bundle args) {
12438        return enqueueAssistContext(requestType, intent, hint, null, null, null,
12439                true /* focused */, true /* newSessionId */,
12440                userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12441    }
12442
12443    public void registerProcessObserver(IProcessObserver observer) {
12444        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12445                "registerProcessObserver()");
12446        synchronized (this) {
12447            mProcessObservers.register(observer);
12448        }
12449    }
12450
12451    @Override
12452    public void unregisterProcessObserver(IProcessObserver observer) {
12453        synchronized (this) {
12454            mProcessObservers.unregister(observer);
12455        }
12456    }
12457
12458    @Override
12459    public void registerUidObserver(IUidObserver observer, int which) {
12460        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12461                "registerUidObserver()");
12462        synchronized (this) {
12463            mUidObservers.register(observer, which);
12464        }
12465    }
12466
12467    @Override
12468    public void unregisterUidObserver(IUidObserver observer) {
12469        synchronized (this) {
12470            mUidObservers.unregister(observer);
12471        }
12472    }
12473
12474    @Override
12475    public boolean convertFromTranslucent(IBinder token) {
12476        final long origId = Binder.clearCallingIdentity();
12477        try {
12478            synchronized (this) {
12479                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12480                if (r == null) {
12481                    return false;
12482                }
12483                final boolean translucentChanged = r.changeWindowTranslucency(true);
12484                if (translucentChanged) {
12485                    r.task.stack.releaseBackgroundResources(r);
12486                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12487                }
12488                mWindowManager.setAppFullscreen(token, true);
12489                return translucentChanged;
12490            }
12491        } finally {
12492            Binder.restoreCallingIdentity(origId);
12493        }
12494    }
12495
12496    @Override
12497    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12498        final long origId = Binder.clearCallingIdentity();
12499        try {
12500            synchronized (this) {
12501                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12502                if (r == null) {
12503                    return false;
12504                }
12505                int index = r.task.mActivities.lastIndexOf(r);
12506                if (index > 0) {
12507                    ActivityRecord under = r.task.mActivities.get(index - 1);
12508                    under.returningOptions = options;
12509                }
12510                final boolean translucentChanged = r.changeWindowTranslucency(false);
12511                if (translucentChanged) {
12512                    r.task.stack.convertActivityToTranslucent(r);
12513                }
12514                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12515                mWindowManager.setAppFullscreen(token, false);
12516                return translucentChanged;
12517            }
12518        } finally {
12519            Binder.restoreCallingIdentity(origId);
12520        }
12521    }
12522
12523    @Override
12524    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12525        final long origId = Binder.clearCallingIdentity();
12526        try {
12527            synchronized (this) {
12528                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12529                if (r != null) {
12530                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12531                }
12532            }
12533            return false;
12534        } finally {
12535            Binder.restoreCallingIdentity(origId);
12536        }
12537    }
12538
12539    @Override
12540    public boolean isBackgroundVisibleBehind(IBinder token) {
12541        final long origId = Binder.clearCallingIdentity();
12542        try {
12543            synchronized (this) {
12544                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12545                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12546                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12547                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12548                return visible;
12549            }
12550        } finally {
12551            Binder.restoreCallingIdentity(origId);
12552        }
12553    }
12554
12555    @Override
12556    public ActivityOptions getActivityOptions(IBinder token) {
12557        final long origId = Binder.clearCallingIdentity();
12558        try {
12559            synchronized (this) {
12560                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12561                if (r != null) {
12562                    final ActivityOptions activityOptions = r.pendingOptions;
12563                    r.pendingOptions = null;
12564                    return activityOptions;
12565                }
12566                return null;
12567            }
12568        } finally {
12569            Binder.restoreCallingIdentity(origId);
12570        }
12571    }
12572
12573    @Override
12574    public void setImmersive(IBinder token, boolean immersive) {
12575        synchronized(this) {
12576            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12577            if (r == null) {
12578                throw new IllegalArgumentException();
12579            }
12580            r.immersive = immersive;
12581
12582            // update associated state if we're frontmost
12583            if (r == mFocusedActivity) {
12584                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12585                applyUpdateLockStateLocked(r);
12586            }
12587        }
12588    }
12589
12590    @Override
12591    public boolean isImmersive(IBinder token) {
12592        synchronized (this) {
12593            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12594            if (r == null) {
12595                throw new IllegalArgumentException();
12596            }
12597            return r.immersive;
12598        }
12599    }
12600
12601    public void setVrThread(int tid) {
12602        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12603            throw new UnsupportedOperationException("VR mode not supported on this device!");
12604        }
12605
12606        synchronized (this) {
12607            ProcessRecord proc;
12608            synchronized (mPidsSelfLocked) {
12609                final int pid = Binder.getCallingPid();
12610                proc = mPidsSelfLocked.get(pid);
12611
12612                if (proc != null && mInVrMode && tid >= 0) {
12613                    // ensure the tid belongs to the process
12614                    if (!Process.isThreadInProcess(pid, tid)) {
12615                        throw new IllegalArgumentException("VR thread does not belong to process");
12616                    }
12617
12618                    // reset existing VR thread to CFS if this thread still exists and belongs to
12619                    // the calling process
12620                    if (proc.vrThreadTid != 0
12621                            && Process.isThreadInProcess(pid, proc.vrThreadTid)) {
12622                        try {
12623                            Process.setThreadScheduler(proc.vrThreadTid, Process.SCHED_OTHER, 0);
12624                        } catch (IllegalArgumentException e) {
12625                            // Ignore this.  Only occurs in race condition where previous VR thread
12626                            // was destroyed during this method call.
12627                        }
12628                    }
12629
12630                    proc.vrThreadTid = tid;
12631
12632                    // promote to FIFO now if the tid is non-zero
12633                    try {
12634                        if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
12635                            proc.vrThreadTid > 0) {
12636                            Process.setThreadScheduler(proc.vrThreadTid,
12637                                Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12638                        }
12639                    } catch (IllegalArgumentException e) {
12640                        Slog.e(TAG, "Failed to set scheduling policy, thread does"
12641                               + " not exist:\n" + e);
12642                    }
12643                }
12644            }
12645        }
12646    }
12647
12648    @Override
12649    public void setRenderThread(int tid) {
12650        synchronized (this) {
12651            ProcessRecord proc;
12652            synchronized (mPidsSelfLocked) {
12653                int pid = Binder.getCallingPid();
12654                proc = mPidsSelfLocked.get(pid);
12655                if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
12656                    // ensure the tid belongs to the process
12657                    if (!Process.isThreadInProcess(pid, tid)) {
12658                        throw new IllegalArgumentException(
12659                            "Render thread does not belong to process");
12660                    }
12661                    proc.renderThreadTid = tid;
12662                    if (DEBUG_OOM_ADJ) {
12663                        Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
12664                    }
12665                    // promote to FIFO now
12666                    if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
12667                        if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
12668                        if (mUseFifoUiScheduling) {
12669                            Process.setThreadScheduler(proc.renderThreadTid,
12670                                Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12671                        } else {
12672                            Process.setThreadPriority(proc.renderThreadTid, -10);
12673                        }
12674                    }
12675                } else {
12676                    if (DEBUG_OOM_ADJ) {
12677                        Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
12678                               "PID: " + pid + ", TID: " + tid + " FIFO: " +
12679                               mUseFifoUiScheduling);
12680                    }
12681                }
12682            }
12683        }
12684    }
12685
12686    @Override
12687    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12688        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12689            throw new UnsupportedOperationException("VR mode not supported on this device!");
12690        }
12691
12692        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12693
12694        ActivityRecord r;
12695        synchronized (this) {
12696            r = ActivityRecord.isInStackLocked(token);
12697        }
12698
12699        if (r == null) {
12700            throw new IllegalArgumentException();
12701        }
12702
12703        int err;
12704        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12705                VrManagerInternal.NO_ERROR) {
12706            return err;
12707        }
12708
12709        synchronized(this) {
12710            r.requestedVrComponent = (enabled) ? packageName : null;
12711
12712            // Update associated state if this activity is currently focused
12713            if (r == mFocusedActivity) {
12714                applyUpdateVrModeLocked(r);
12715            }
12716            return 0;
12717        }
12718    }
12719
12720    @Override
12721    public boolean isVrModePackageEnabled(ComponentName packageName) {
12722        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12723            throw new UnsupportedOperationException("VR mode not supported on this device!");
12724        }
12725
12726        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12727
12728        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12729                VrManagerInternal.NO_ERROR;
12730    }
12731
12732    public boolean isTopActivityImmersive() {
12733        enforceNotIsolatedCaller("startActivity");
12734        synchronized (this) {
12735            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12736            return (r != null) ? r.immersive : false;
12737        }
12738    }
12739
12740    @Override
12741    public boolean isTopOfTask(IBinder token) {
12742        synchronized (this) {
12743            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12744            if (r == null) {
12745                throw new IllegalArgumentException();
12746            }
12747            return r.task.getTopActivity() == r;
12748        }
12749    }
12750
12751    @Override
12752    public void setHasTopUi(boolean hasTopUi) throws RemoteException {
12753        if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
12754            String msg = "Permission Denial: setHasTopUi() from pid="
12755                    + Binder.getCallingPid()
12756                    + ", uid=" + Binder.getCallingUid()
12757                    + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
12758            Slog.w(TAG, msg);
12759            throw new SecurityException(msg);
12760        }
12761        final int pid = Binder.getCallingPid();
12762        final long origId = Binder.clearCallingIdentity();
12763        try {
12764            synchronized (this) {
12765                boolean changed = false;
12766                ProcessRecord pr;
12767                synchronized (mPidsSelfLocked) {
12768                    pr = mPidsSelfLocked.get(pid);
12769                    if (pr == null) {
12770                        Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
12771                        return;
12772                    }
12773                    if (pr.hasTopUi != hasTopUi) {
12774                        Slog.i(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
12775                        pr.hasTopUi = hasTopUi;
12776                        changed = true;
12777                    }
12778                }
12779                if (changed) {
12780                    updateOomAdjLocked(pr);
12781                }
12782            }
12783        } finally {
12784            Binder.restoreCallingIdentity(origId);
12785        }
12786    }
12787
12788    public final void enterSafeMode() {
12789        synchronized(this) {
12790            // It only makes sense to do this before the system is ready
12791            // and started launching other packages.
12792            if (!mSystemReady) {
12793                try {
12794                    AppGlobals.getPackageManager().enterSafeMode();
12795                } catch (RemoteException e) {
12796                }
12797            }
12798
12799            mSafeMode = true;
12800        }
12801    }
12802
12803    public final void showSafeModeOverlay() {
12804        View v = LayoutInflater.from(mContext).inflate(
12805                com.android.internal.R.layout.safe_mode, null);
12806        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12807        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12808        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12809        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12810        lp.gravity = Gravity.BOTTOM | Gravity.START;
12811        lp.format = v.getBackground().getOpacity();
12812        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12813                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12814        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12815        ((WindowManager)mContext.getSystemService(
12816                Context.WINDOW_SERVICE)).addView(v, lp);
12817    }
12818
12819    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12820        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12821            return;
12822        }
12823        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12824        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12825        synchronized (stats) {
12826            if (mBatteryStatsService.isOnBattery()) {
12827                mBatteryStatsService.enforceCallingPermission();
12828                int MY_UID = Binder.getCallingUid();
12829                final int uid;
12830                if (sender == null) {
12831                    uid = sourceUid;
12832                } else {
12833                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12834                }
12835                BatteryStatsImpl.Uid.Pkg pkg =
12836                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12837                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12838                pkg.noteWakeupAlarmLocked(tag);
12839            }
12840        }
12841    }
12842
12843    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12844        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12845            return;
12846        }
12847        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12848        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12849        synchronized (stats) {
12850            mBatteryStatsService.enforceCallingPermission();
12851            int MY_UID = Binder.getCallingUid();
12852            final int uid;
12853            if (sender == null) {
12854                uid = sourceUid;
12855            } else {
12856                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12857            }
12858            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12859        }
12860    }
12861
12862    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12863        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12864            return;
12865        }
12866        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12867        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12868        synchronized (stats) {
12869            mBatteryStatsService.enforceCallingPermission();
12870            int MY_UID = Binder.getCallingUid();
12871            final int uid;
12872            if (sender == null) {
12873                uid = sourceUid;
12874            } else {
12875                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12876            }
12877            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12878        }
12879    }
12880
12881    public boolean killPids(int[] pids, String pReason, boolean secure) {
12882        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12883            throw new SecurityException("killPids only available to the system");
12884        }
12885        String reason = (pReason == null) ? "Unknown" : pReason;
12886        // XXX Note: don't acquire main activity lock here, because the window
12887        // manager calls in with its locks held.
12888
12889        boolean killed = false;
12890        synchronized (mPidsSelfLocked) {
12891            int worstType = 0;
12892            for (int i=0; i<pids.length; i++) {
12893                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12894                if (proc != null) {
12895                    int type = proc.setAdj;
12896                    if (type > worstType) {
12897                        worstType = type;
12898                    }
12899                }
12900            }
12901
12902            // If the worst oom_adj is somewhere in the cached proc LRU range,
12903            // then constrain it so we will kill all cached procs.
12904            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12905                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12906                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12907            }
12908
12909            // If this is not a secure call, don't let it kill processes that
12910            // are important.
12911            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12912                worstType = ProcessList.SERVICE_ADJ;
12913            }
12914
12915            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12916            for (int i=0; i<pids.length; i++) {
12917                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12918                if (proc == null) {
12919                    continue;
12920                }
12921                int adj = proc.setAdj;
12922                if (adj >= worstType && !proc.killedByAm) {
12923                    proc.kill(reason, true);
12924                    killed = true;
12925                }
12926            }
12927        }
12928        return killed;
12929    }
12930
12931    @Override
12932    public void killUid(int appId, int userId, String reason) {
12933        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12934        synchronized (this) {
12935            final long identity = Binder.clearCallingIdentity();
12936            try {
12937                killPackageProcessesLocked(null, appId, userId,
12938                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12939                        reason != null ? reason : "kill uid");
12940            } finally {
12941                Binder.restoreCallingIdentity(identity);
12942            }
12943        }
12944    }
12945
12946    @Override
12947    public boolean killProcessesBelowForeground(String reason) {
12948        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12949            throw new SecurityException("killProcessesBelowForeground() only available to system");
12950        }
12951
12952        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12953    }
12954
12955    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12956        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12957            throw new SecurityException("killProcessesBelowAdj() only available to system");
12958        }
12959
12960        boolean killed = false;
12961        synchronized (mPidsSelfLocked) {
12962            final int size = mPidsSelfLocked.size();
12963            for (int i = 0; i < size; i++) {
12964                final int pid = mPidsSelfLocked.keyAt(i);
12965                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12966                if (proc == null) continue;
12967
12968                final int adj = proc.setAdj;
12969                if (adj > belowAdj && !proc.killedByAm) {
12970                    proc.kill(reason, true);
12971                    killed = true;
12972                }
12973            }
12974        }
12975        return killed;
12976    }
12977
12978    @Override
12979    public void hang(final IBinder who, boolean allowRestart) {
12980        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12981                != PackageManager.PERMISSION_GRANTED) {
12982            throw new SecurityException("Requires permission "
12983                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12984        }
12985
12986        final IBinder.DeathRecipient death = new DeathRecipient() {
12987            @Override
12988            public void binderDied() {
12989                synchronized (this) {
12990                    notifyAll();
12991                }
12992            }
12993        };
12994
12995        try {
12996            who.linkToDeath(death, 0);
12997        } catch (RemoteException e) {
12998            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12999            return;
13000        }
13001
13002        synchronized (this) {
13003            Watchdog.getInstance().setAllowRestart(allowRestart);
13004            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
13005            synchronized (death) {
13006                while (who.isBinderAlive()) {
13007                    try {
13008                        death.wait();
13009                    } catch (InterruptedException e) {
13010                    }
13011                }
13012            }
13013            Watchdog.getInstance().setAllowRestart(true);
13014        }
13015    }
13016
13017    @Override
13018    public void restart() {
13019        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13020                != PackageManager.PERMISSION_GRANTED) {
13021            throw new SecurityException("Requires permission "
13022                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13023        }
13024
13025        Log.i(TAG, "Sending shutdown broadcast...");
13026
13027        BroadcastReceiver br = new BroadcastReceiver() {
13028            @Override public void onReceive(Context context, Intent intent) {
13029                // Now the broadcast is done, finish up the low-level shutdown.
13030                Log.i(TAG, "Shutting down activity manager...");
13031                shutdown(10000);
13032                Log.i(TAG, "Shutdown complete, restarting!");
13033                Process.killProcess(Process.myPid());
13034                System.exit(10);
13035            }
13036        };
13037
13038        // First send the high-level shut down broadcast.
13039        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
13040        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
13041        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
13042        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
13043        mContext.sendOrderedBroadcastAsUser(intent,
13044                UserHandle.ALL, null, br, mHandler, 0, null, null);
13045        */
13046        br.onReceive(mContext, intent);
13047    }
13048
13049    private long getLowRamTimeSinceIdle(long now) {
13050        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
13051    }
13052
13053    @Override
13054    public void performIdleMaintenance() {
13055        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13056                != PackageManager.PERMISSION_GRANTED) {
13057            throw new SecurityException("Requires permission "
13058                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13059        }
13060
13061        synchronized (this) {
13062            final long now = SystemClock.uptimeMillis();
13063            final long timeSinceLastIdle = now - mLastIdleTime;
13064            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
13065            mLastIdleTime = now;
13066            mLowRamTimeSinceLastIdle = 0;
13067            if (mLowRamStartTime != 0) {
13068                mLowRamStartTime = now;
13069            }
13070
13071            StringBuilder sb = new StringBuilder(128);
13072            sb.append("Idle maintenance over ");
13073            TimeUtils.formatDuration(timeSinceLastIdle, sb);
13074            sb.append(" low RAM for ");
13075            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13076            Slog.i(TAG, sb.toString());
13077
13078            // If at least 1/3 of our time since the last idle period has been spent
13079            // with RAM low, then we want to kill processes.
13080            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
13081
13082            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13083                ProcessRecord proc = mLruProcesses.get(i);
13084                if (proc.notCachedSinceIdle) {
13085                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
13086                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
13087                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
13088                        if (doKilling && proc.initialIdlePss != 0
13089                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
13090                            sb = new StringBuilder(128);
13091                            sb.append("Kill");
13092                            sb.append(proc.processName);
13093                            sb.append(" in idle maint: pss=");
13094                            sb.append(proc.lastPss);
13095                            sb.append(", swapPss=");
13096                            sb.append(proc.lastSwapPss);
13097                            sb.append(", initialPss=");
13098                            sb.append(proc.initialIdlePss);
13099                            sb.append(", period=");
13100                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
13101                            sb.append(", lowRamPeriod=");
13102                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13103                            Slog.wtfQuiet(TAG, sb.toString());
13104                            proc.kill("idle maint (pss " + proc.lastPss
13105                                    + " from " + proc.initialIdlePss + ")", true);
13106                        }
13107                    }
13108                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
13109                        && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
13110                    proc.notCachedSinceIdle = true;
13111                    proc.initialIdlePss = 0;
13112                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
13113                            mTestPssMode, isSleepingLocked(), now);
13114                }
13115            }
13116
13117            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
13118            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
13119        }
13120    }
13121
13122    @Override
13123    public void sendIdleJobTrigger() {
13124        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13125                != PackageManager.PERMISSION_GRANTED) {
13126            throw new SecurityException("Requires permission "
13127                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13128        }
13129
13130        final long ident = Binder.clearCallingIdentity();
13131        try {
13132            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
13133                    .setPackage("android")
13134                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13135            broadcastIntent(null, intent, null, null, 0, null, null, null,
13136                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
13137        } finally {
13138            Binder.restoreCallingIdentity(ident);
13139        }
13140    }
13141
13142    private void retrieveSettings() {
13143        final ContentResolver resolver = mContext.getContentResolver();
13144        final boolean freeformWindowManagement =
13145                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
13146                        || Settings.Global.getInt(
13147                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
13148        final boolean supportsPictureInPicture =
13149                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
13150
13151        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
13152        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
13153        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
13154        final boolean alwaysFinishActivities =
13155                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
13156        final boolean lenientBackgroundCheck =
13157                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
13158        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
13159        final boolean forceResizable = Settings.Global.getInt(
13160                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
13161        final boolean supportsLeanbackOnly =
13162                mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
13163
13164        // Transfer any global setting for forcing RTL layout, into a System Property
13165        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
13166
13167        final Configuration configuration = new Configuration();
13168        Settings.System.getConfiguration(resolver, configuration);
13169        if (forceRtl) {
13170            // This will take care of setting the correct layout direction flags
13171            configuration.setLayoutDirection(configuration.locale);
13172        }
13173
13174        synchronized (this) {
13175            mDebugApp = mOrigDebugApp = debugApp;
13176            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
13177            mAlwaysFinishActivities = alwaysFinishActivities;
13178            mLenientBackgroundCheck = lenientBackgroundCheck;
13179            mSupportsLeanbackOnly = supportsLeanbackOnly;
13180            mForceResizableActivities = forceResizable;
13181            mWindowManager.setForceResizableTasks(mForceResizableActivities);
13182            if (supportsMultiWindow || forceResizable) {
13183                mSupportsMultiWindow = true;
13184                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
13185                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
13186            } else {
13187                mSupportsMultiWindow = false;
13188                mSupportsFreeformWindowManagement = false;
13189                mSupportsPictureInPicture = false;
13190            }
13191            // This happens before any activities are started, so we can
13192            // change mConfiguration in-place.
13193            updateConfigurationLocked(configuration, null, true);
13194            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
13195                    "Initial config: " + mConfiguration);
13196
13197            // Load resources only after the current configuration has been set.
13198            final Resources res = mContext.getResources();
13199            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
13200            mThumbnailWidth = res.getDimensionPixelSize(
13201                    com.android.internal.R.dimen.thumbnail_width);
13202            mThumbnailHeight = res.getDimensionPixelSize(
13203                    com.android.internal.R.dimen.thumbnail_height);
13204            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
13205                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
13206            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
13207                    com.android.internal.R.string.config_appsNotReportingCrashes));
13208            if ((mConfiguration.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
13209                mFullscreenThumbnailScale = (float) res
13210                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
13211                    (float) mConfiguration.screenWidthDp;
13212            } else {
13213                mFullscreenThumbnailScale = res.getFraction(
13214                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
13215            }
13216        }
13217    }
13218
13219    public boolean testIsSystemReady() {
13220        // no need to synchronize(this) just to read & return the value
13221        return mSystemReady;
13222    }
13223
13224    public void systemReady(final Runnable goingCallback) {
13225        synchronized(this) {
13226            if (mSystemReady) {
13227                // If we're done calling all the receivers, run the next "boot phase" passed in
13228                // by the SystemServer
13229                if (goingCallback != null) {
13230                    goingCallback.run();
13231                }
13232                return;
13233            }
13234
13235            mLocalDeviceIdleController
13236                    = LocalServices.getService(DeviceIdleController.LocalService.class);
13237
13238            // Make sure we have the current profile info, since it is needed for security checks.
13239            mUserController.onSystemReady();
13240            mRecentTasks.onSystemReadyLocked();
13241            mAppOpsService.systemReady();
13242            mSystemReady = true;
13243        }
13244
13245        ArrayList<ProcessRecord> procsToKill = null;
13246        synchronized(mPidsSelfLocked) {
13247            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
13248                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13249                if (!isAllowedWhileBooting(proc.info)){
13250                    if (procsToKill == null) {
13251                        procsToKill = new ArrayList<ProcessRecord>();
13252                    }
13253                    procsToKill.add(proc);
13254                }
13255            }
13256        }
13257
13258        synchronized(this) {
13259            if (procsToKill != null) {
13260                for (int i=procsToKill.size()-1; i>=0; i--) {
13261                    ProcessRecord proc = procsToKill.get(i);
13262                    Slog.i(TAG, "Removing system update proc: " + proc);
13263                    removeProcessLocked(proc, true, false, "system update done");
13264                }
13265            }
13266
13267            // Now that we have cleaned up any update processes, we
13268            // are ready to start launching real processes and know that
13269            // we won't trample on them any more.
13270            mProcessesReady = true;
13271        }
13272
13273        Slog.i(TAG, "System now ready");
13274        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
13275            SystemClock.uptimeMillis());
13276
13277        synchronized(this) {
13278            // Make sure we have no pre-ready processes sitting around.
13279
13280            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
13281                ResolveInfo ri = mContext.getPackageManager()
13282                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
13283                                STOCK_PM_FLAGS);
13284                CharSequence errorMsg = null;
13285                if (ri != null) {
13286                    ActivityInfo ai = ri.activityInfo;
13287                    ApplicationInfo app = ai.applicationInfo;
13288                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
13289                        mTopAction = Intent.ACTION_FACTORY_TEST;
13290                        mTopData = null;
13291                        mTopComponent = new ComponentName(app.packageName,
13292                                ai.name);
13293                    } else {
13294                        errorMsg = mContext.getResources().getText(
13295                                com.android.internal.R.string.factorytest_not_system);
13296                    }
13297                } else {
13298                    errorMsg = mContext.getResources().getText(
13299                            com.android.internal.R.string.factorytest_no_action);
13300                }
13301                if (errorMsg != null) {
13302                    mTopAction = null;
13303                    mTopData = null;
13304                    mTopComponent = null;
13305                    Message msg = Message.obtain();
13306                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
13307                    msg.getData().putCharSequence("msg", errorMsg);
13308                    mUiHandler.sendMessage(msg);
13309                }
13310            }
13311        }
13312
13313        retrieveSettings();
13314        final int currentUserId;
13315        synchronized (this) {
13316            currentUserId = mUserController.getCurrentUserIdLocked();
13317            readGrantedUriPermissionsLocked();
13318        }
13319
13320        if (goingCallback != null) goingCallback.run();
13321
13322        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
13323                Integer.toString(currentUserId), currentUserId);
13324        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
13325                Integer.toString(currentUserId), currentUserId);
13326        mSystemServiceManager.startUser(currentUserId);
13327
13328        synchronized (this) {
13329            // Only start up encryption-aware persistent apps; once user is
13330            // unlocked we'll come back around and start unaware apps
13331            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
13332
13333            // Start up initial activity.
13334            mBooting = true;
13335            // Enable home activity for system user, so that the system can always boot
13336            if (UserManager.isSplitSystemUser()) {
13337                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
13338                try {
13339                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
13340                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
13341                            UserHandle.USER_SYSTEM);
13342                } catch (RemoteException e) {
13343                    throw e.rethrowAsRuntimeException();
13344                }
13345            }
13346            startHomeActivityLocked(currentUserId, "systemReady");
13347
13348            try {
13349                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
13350                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
13351                            + " data partition or your device will be unstable.");
13352                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
13353                }
13354            } catch (RemoteException e) {
13355            }
13356
13357            if (!Build.isBuildConsistent()) {
13358                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
13359                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
13360            }
13361
13362            long ident = Binder.clearCallingIdentity();
13363            try {
13364                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
13365                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13366                        | Intent.FLAG_RECEIVER_FOREGROUND);
13367                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13368                broadcastIntentLocked(null, null, intent,
13369                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
13370                        null, false, false, MY_PID, Process.SYSTEM_UID,
13371                        currentUserId);
13372                intent = new Intent(Intent.ACTION_USER_STARTING);
13373                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13374                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13375                broadcastIntentLocked(null, null, intent,
13376                        null, new IIntentReceiver.Stub() {
13377                            @Override
13378                            public void performReceive(Intent intent, int resultCode, String data,
13379                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13380                                    throws RemoteException {
13381                            }
13382                        }, 0, null, null,
13383                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13384                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13385            } catch (Throwable t) {
13386                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13387            } finally {
13388                Binder.restoreCallingIdentity(ident);
13389            }
13390            mStackSupervisor.resumeFocusedStackTopActivityLocked();
13391            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13392        }
13393    }
13394
13395    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13396        synchronized (this) {
13397            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13398        }
13399    }
13400
13401    void skipCurrentReceiverLocked(ProcessRecord app) {
13402        for (BroadcastQueue queue : mBroadcastQueues) {
13403            queue.skipCurrentReceiverLocked(app);
13404        }
13405    }
13406
13407    /**
13408     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13409     * The application process will exit immediately after this call returns.
13410     * @param app object of the crashing app, null for the system server
13411     * @param crashInfo describing the exception
13412     */
13413    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
13414        ProcessRecord r = findAppProcess(app, "Crash");
13415        final String processName = app == null ? "system_server"
13416                : (r == null ? "unknown" : r.processName);
13417
13418        handleApplicationCrashInner("crash", r, processName, crashInfo);
13419    }
13420
13421    /* Native crash reporting uses this inner version because it needs to be somewhat
13422     * decoupled from the AM-managed cleanup lifecycle
13423     */
13424    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13425            ApplicationErrorReport.CrashInfo crashInfo) {
13426        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13427                UserHandle.getUserId(Binder.getCallingUid()), processName,
13428                r == null ? -1 : r.info.flags,
13429                crashInfo.exceptionClassName,
13430                crashInfo.exceptionMessage,
13431                crashInfo.throwFileName,
13432                crashInfo.throwLineNumber);
13433
13434        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13435
13436        mAppErrors.crashApplication(r, crashInfo);
13437    }
13438
13439    public void handleApplicationStrictModeViolation(
13440            IBinder app,
13441            int violationMask,
13442            StrictMode.ViolationInfo info) {
13443        ProcessRecord r = findAppProcess(app, "StrictMode");
13444        if (r == null) {
13445            return;
13446        }
13447
13448        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13449            Integer stackFingerprint = info.hashCode();
13450            boolean logIt = true;
13451            synchronized (mAlreadyLoggedViolatedStacks) {
13452                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13453                    logIt = false;
13454                    // TODO: sub-sample into EventLog for these, with
13455                    // the info.durationMillis?  Then we'd get
13456                    // the relative pain numbers, without logging all
13457                    // the stack traces repeatedly.  We'd want to do
13458                    // likewise in the client code, which also does
13459                    // dup suppression, before the Binder call.
13460                } else {
13461                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13462                        mAlreadyLoggedViolatedStacks.clear();
13463                    }
13464                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13465                }
13466            }
13467            if (logIt) {
13468                logStrictModeViolationToDropBox(r, info);
13469            }
13470        }
13471
13472        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13473            AppErrorResult result = new AppErrorResult();
13474            synchronized (this) {
13475                final long origId = Binder.clearCallingIdentity();
13476
13477                Message msg = Message.obtain();
13478                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13479                HashMap<String, Object> data = new HashMap<String, Object>();
13480                data.put("result", result);
13481                data.put("app", r);
13482                data.put("violationMask", violationMask);
13483                data.put("info", info);
13484                msg.obj = data;
13485                mUiHandler.sendMessage(msg);
13486
13487                Binder.restoreCallingIdentity(origId);
13488            }
13489            int res = result.get();
13490            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13491        }
13492    }
13493
13494    // Depending on the policy in effect, there could be a bunch of
13495    // these in quick succession so we try to batch these together to
13496    // minimize disk writes, number of dropbox entries, and maximize
13497    // compression, by having more fewer, larger records.
13498    private void logStrictModeViolationToDropBox(
13499            ProcessRecord process,
13500            StrictMode.ViolationInfo info) {
13501        if (info == null) {
13502            return;
13503        }
13504        final boolean isSystemApp = process == null ||
13505                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13506                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13507        final String processName = process == null ? "unknown" : process.processName;
13508        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13509        final DropBoxManager dbox = (DropBoxManager)
13510                mContext.getSystemService(Context.DROPBOX_SERVICE);
13511
13512        // Exit early if the dropbox isn't configured to accept this report type.
13513        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13514
13515        boolean bufferWasEmpty;
13516        boolean needsFlush;
13517        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13518        synchronized (sb) {
13519            bufferWasEmpty = sb.length() == 0;
13520            appendDropBoxProcessHeaders(process, processName, sb);
13521            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13522            sb.append("System-App: ").append(isSystemApp).append("\n");
13523            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13524            if (info.violationNumThisLoop != 0) {
13525                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13526            }
13527            if (info.numAnimationsRunning != 0) {
13528                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13529            }
13530            if (info.broadcastIntentAction != null) {
13531                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13532            }
13533            if (info.durationMillis != -1) {
13534                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13535            }
13536            if (info.numInstances != -1) {
13537                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13538            }
13539            if (info.tags != null) {
13540                for (String tag : info.tags) {
13541                    sb.append("Span-Tag: ").append(tag).append("\n");
13542                }
13543            }
13544            sb.append("\n");
13545            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13546                sb.append(info.crashInfo.stackTrace);
13547                sb.append("\n");
13548            }
13549            if (info.message != null) {
13550                sb.append(info.message);
13551                sb.append("\n");
13552            }
13553
13554            // Only buffer up to ~64k.  Various logging bits truncate
13555            // things at 128k.
13556            needsFlush = (sb.length() > 64 * 1024);
13557        }
13558
13559        // Flush immediately if the buffer's grown too large, or this
13560        // is a non-system app.  Non-system apps are isolated with a
13561        // different tag & policy and not batched.
13562        //
13563        // Batching is useful during internal testing with
13564        // StrictMode settings turned up high.  Without batching,
13565        // thousands of separate files could be created on boot.
13566        if (!isSystemApp || needsFlush) {
13567            new Thread("Error dump: " + dropboxTag) {
13568                @Override
13569                public void run() {
13570                    String report;
13571                    synchronized (sb) {
13572                        report = sb.toString();
13573                        sb.delete(0, sb.length());
13574                        sb.trimToSize();
13575                    }
13576                    if (report.length() != 0) {
13577                        dbox.addText(dropboxTag, report);
13578                    }
13579                }
13580            }.start();
13581            return;
13582        }
13583
13584        // System app batching:
13585        if (!bufferWasEmpty) {
13586            // An existing dropbox-writing thread is outstanding, so
13587            // we don't need to start it up.  The existing thread will
13588            // catch the buffer appends we just did.
13589            return;
13590        }
13591
13592        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13593        // (After this point, we shouldn't access AMS internal data structures.)
13594        new Thread("Error dump: " + dropboxTag) {
13595            @Override
13596            public void run() {
13597                // 5 second sleep to let stacks arrive and be batched together
13598                try {
13599                    Thread.sleep(5000);  // 5 seconds
13600                } catch (InterruptedException e) {}
13601
13602                String errorReport;
13603                synchronized (mStrictModeBuffer) {
13604                    errorReport = mStrictModeBuffer.toString();
13605                    if (errorReport.length() == 0) {
13606                        return;
13607                    }
13608                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13609                    mStrictModeBuffer.trimToSize();
13610                }
13611                dbox.addText(dropboxTag, errorReport);
13612            }
13613        }.start();
13614    }
13615
13616    /**
13617     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13618     * @param app object of the crashing app, null for the system server
13619     * @param tag reported by the caller
13620     * @param system whether this wtf is coming from the system
13621     * @param crashInfo describing the context of the error
13622     * @return true if the process should exit immediately (WTF is fatal)
13623     */
13624    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13625            final ApplicationErrorReport.CrashInfo crashInfo) {
13626        final int callingUid = Binder.getCallingUid();
13627        final int callingPid = Binder.getCallingPid();
13628
13629        if (system) {
13630            // If this is coming from the system, we could very well have low-level
13631            // system locks held, so we want to do this all asynchronously.  And we
13632            // never want this to become fatal, so there is that too.
13633            mHandler.post(new Runnable() {
13634                @Override public void run() {
13635                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13636                }
13637            });
13638            return false;
13639        }
13640
13641        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13642                crashInfo);
13643
13644        if (r != null && r.pid != Process.myPid() &&
13645                Settings.Global.getInt(mContext.getContentResolver(),
13646                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13647            mAppErrors.crashApplication(r, crashInfo);
13648            return true;
13649        } else {
13650            return false;
13651        }
13652    }
13653
13654    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13655            final ApplicationErrorReport.CrashInfo crashInfo) {
13656        final ProcessRecord r = findAppProcess(app, "WTF");
13657        final String processName = app == null ? "system_server"
13658                : (r == null ? "unknown" : r.processName);
13659
13660        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13661                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13662
13663        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13664
13665        return r;
13666    }
13667
13668    /**
13669     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13670     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13671     */
13672    private ProcessRecord findAppProcess(IBinder app, String reason) {
13673        if (app == null) {
13674            return null;
13675        }
13676
13677        synchronized (this) {
13678            final int NP = mProcessNames.getMap().size();
13679            for (int ip=0; ip<NP; ip++) {
13680                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13681                final int NA = apps.size();
13682                for (int ia=0; ia<NA; ia++) {
13683                    ProcessRecord p = apps.valueAt(ia);
13684                    if (p.thread != null && p.thread.asBinder() == app) {
13685                        return p;
13686                    }
13687                }
13688            }
13689
13690            Slog.w(TAG, "Can't find mystery application for " + reason
13691                    + " from pid=" + Binder.getCallingPid()
13692                    + " uid=" + Binder.getCallingUid() + ": " + app);
13693            return null;
13694        }
13695    }
13696
13697    /**
13698     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13699     * to append various headers to the dropbox log text.
13700     */
13701    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13702            StringBuilder sb) {
13703        // Watchdog thread ends up invoking this function (with
13704        // a null ProcessRecord) to add the stack file to dropbox.
13705        // Do not acquire a lock on this (am) in such cases, as it
13706        // could cause a potential deadlock, if and when watchdog
13707        // is invoked due to unavailability of lock on am and it
13708        // would prevent watchdog from killing system_server.
13709        if (process == null) {
13710            sb.append("Process: ").append(processName).append("\n");
13711            return;
13712        }
13713        // Note: ProcessRecord 'process' is guarded by the service
13714        // instance.  (notably process.pkgList, which could otherwise change
13715        // concurrently during execution of this method)
13716        synchronized (this) {
13717            sb.append("Process: ").append(processName).append("\n");
13718            int flags = process.info.flags;
13719            IPackageManager pm = AppGlobals.getPackageManager();
13720            sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
13721            for (int ip=0; ip<process.pkgList.size(); ip++) {
13722                String pkg = process.pkgList.keyAt(ip);
13723                sb.append("Package: ").append(pkg);
13724                try {
13725                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13726                    if (pi != null) {
13727                        sb.append(" v").append(pi.versionCode);
13728                        if (pi.versionName != null) {
13729                            sb.append(" (").append(pi.versionName).append(")");
13730                        }
13731                    }
13732                } catch (RemoteException e) {
13733                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13734                }
13735                sb.append("\n");
13736            }
13737        }
13738    }
13739
13740    private static String processClass(ProcessRecord process) {
13741        if (process == null || process.pid == MY_PID) {
13742            return "system_server";
13743        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13744            return "system_app";
13745        } else {
13746            return "data_app";
13747        }
13748    }
13749
13750    private volatile long mWtfClusterStart;
13751    private volatile int mWtfClusterCount;
13752
13753    /**
13754     * Write a description of an error (crash, WTF, ANR) to the drop box.
13755     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13756     * @param process which caused the error, null means the system server
13757     * @param activity which triggered the error, null if unknown
13758     * @param parent activity related to the error, null if unknown
13759     * @param subject line related to the error, null if absent
13760     * @param report in long form describing the error, null if absent
13761     * @param dataFile text file to include in the report, null if none
13762     * @param crashInfo giving an application stack trace, null if absent
13763     */
13764    public void addErrorToDropBox(String eventType,
13765            ProcessRecord process, String processName, ActivityRecord activity,
13766            ActivityRecord parent, String subject,
13767            final String report, final File dataFile,
13768            final ApplicationErrorReport.CrashInfo crashInfo) {
13769        // NOTE -- this must never acquire the ActivityManagerService lock,
13770        // otherwise the watchdog may be prevented from resetting the system.
13771
13772        final String dropboxTag = processClass(process) + "_" + eventType;
13773        final DropBoxManager dbox = (DropBoxManager)
13774                mContext.getSystemService(Context.DROPBOX_SERVICE);
13775
13776        // Exit early if the dropbox isn't configured to accept this report type.
13777        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13778
13779        // Rate-limit how often we're willing to do the heavy lifting below to
13780        // collect and record logs; currently 5 logs per 10 second period.
13781        final long now = SystemClock.elapsedRealtime();
13782        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13783            mWtfClusterStart = now;
13784            mWtfClusterCount = 1;
13785        } else {
13786            if (mWtfClusterCount++ >= 5) return;
13787        }
13788
13789        final StringBuilder sb = new StringBuilder(1024);
13790        appendDropBoxProcessHeaders(process, processName, sb);
13791        if (process != null) {
13792            sb.append("Foreground: ")
13793                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13794                    .append("\n");
13795        }
13796        if (activity != null) {
13797            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13798        }
13799        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13800            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13801        }
13802        if (parent != null && parent != activity) {
13803            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13804        }
13805        if (subject != null) {
13806            sb.append("Subject: ").append(subject).append("\n");
13807        }
13808        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13809        if (Debug.isDebuggerConnected()) {
13810            sb.append("Debugger: Connected\n");
13811        }
13812        sb.append("\n");
13813
13814        // Do the rest in a worker thread to avoid blocking the caller on I/O
13815        // (After this point, we shouldn't access AMS internal data structures.)
13816        Thread worker = new Thread("Error dump: " + dropboxTag) {
13817            @Override
13818            public void run() {
13819                if (report != null) {
13820                    sb.append(report);
13821                }
13822
13823                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13824                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13825                int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
13826                        - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
13827
13828                if (dataFile != null && maxDataFileSize > 0) {
13829                    try {
13830                        sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
13831                                    "\n\n[[TRUNCATED]]"));
13832                    } catch (IOException e) {
13833                        Slog.e(TAG, "Error reading " + dataFile, e);
13834                    }
13835                }
13836                if (crashInfo != null && crashInfo.stackTrace != null) {
13837                    sb.append(crashInfo.stackTrace);
13838                }
13839
13840                if (lines > 0) {
13841                    sb.append("\n");
13842
13843                    // Merge several logcat streams, and take the last N lines
13844                    InputStreamReader input = null;
13845                    try {
13846                        java.lang.Process logcat = new ProcessBuilder(
13847                                "/system/bin/timeout", "-k", "15s", "10s",
13848                                "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
13849                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13850                                        .redirectErrorStream(true).start();
13851
13852                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13853                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13854                        input = new InputStreamReader(logcat.getInputStream());
13855
13856                        int num;
13857                        char[] buf = new char[8192];
13858                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13859                    } catch (IOException e) {
13860                        Slog.e(TAG, "Error running logcat", e);
13861                    } finally {
13862                        if (input != null) try { input.close(); } catch (IOException e) {}
13863                    }
13864                }
13865
13866                dbox.addText(dropboxTag, sb.toString());
13867            }
13868        };
13869
13870        if (process == null) {
13871            // If process is null, we are being called from some internal code
13872            // and may be about to die -- run this synchronously.
13873            worker.run();
13874        } else {
13875            worker.start();
13876        }
13877    }
13878
13879    @Override
13880    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13881        enforceNotIsolatedCaller("getProcessesInErrorState");
13882        // assume our apps are happy - lazy create the list
13883        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13884
13885        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13886                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13887        int userId = UserHandle.getUserId(Binder.getCallingUid());
13888
13889        synchronized (this) {
13890
13891            // iterate across all processes
13892            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13893                ProcessRecord app = mLruProcesses.get(i);
13894                if (!allUsers && app.userId != userId) {
13895                    continue;
13896                }
13897                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13898                    // This one's in trouble, so we'll generate a report for it
13899                    // crashes are higher priority (in case there's a crash *and* an anr)
13900                    ActivityManager.ProcessErrorStateInfo report = null;
13901                    if (app.crashing) {
13902                        report = app.crashingReport;
13903                    } else if (app.notResponding) {
13904                        report = app.notRespondingReport;
13905                    }
13906
13907                    if (report != null) {
13908                        if (errList == null) {
13909                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13910                        }
13911                        errList.add(report);
13912                    } else {
13913                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13914                                " crashing = " + app.crashing +
13915                                " notResponding = " + app.notResponding);
13916                    }
13917                }
13918            }
13919        }
13920
13921        return errList;
13922    }
13923
13924    static int procStateToImportance(int procState, int memAdj,
13925            ActivityManager.RunningAppProcessInfo currApp) {
13926        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13927        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13928            currApp.lru = memAdj;
13929        } else {
13930            currApp.lru = 0;
13931        }
13932        return imp;
13933    }
13934
13935    private void fillInProcMemInfo(ProcessRecord app,
13936            ActivityManager.RunningAppProcessInfo outInfo) {
13937        outInfo.pid = app.pid;
13938        outInfo.uid = app.info.uid;
13939        if (mHeavyWeightProcess == app) {
13940            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13941        }
13942        if (app.persistent) {
13943            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13944        }
13945        if (app.activities.size() > 0) {
13946            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13947        }
13948        outInfo.lastTrimLevel = app.trimMemoryLevel;
13949        int adj = app.curAdj;
13950        int procState = app.curProcState;
13951        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13952        outInfo.importanceReasonCode = app.adjTypeCode;
13953        outInfo.processState = app.curProcState;
13954    }
13955
13956    @Override
13957    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13958        enforceNotIsolatedCaller("getRunningAppProcesses");
13959
13960        final int callingUid = Binder.getCallingUid();
13961
13962        // Lazy instantiation of list
13963        List<ActivityManager.RunningAppProcessInfo> runList = null;
13964        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13965                callingUid) == PackageManager.PERMISSION_GRANTED;
13966        final int userId = UserHandle.getUserId(callingUid);
13967        final boolean allUids = isGetTasksAllowed(
13968                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13969
13970        synchronized (this) {
13971            // Iterate across all processes
13972            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13973                ProcessRecord app = mLruProcesses.get(i);
13974                if ((!allUsers && app.userId != userId)
13975                        || (!allUids && app.uid != callingUid)) {
13976                    continue;
13977                }
13978                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13979                    // Generate process state info for running application
13980                    ActivityManager.RunningAppProcessInfo currApp =
13981                        new ActivityManager.RunningAppProcessInfo(app.processName,
13982                                app.pid, app.getPackageList());
13983                    fillInProcMemInfo(app, currApp);
13984                    if (app.adjSource instanceof ProcessRecord) {
13985                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13986                        currApp.importanceReasonImportance =
13987                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13988                                        app.adjSourceProcState);
13989                    } else if (app.adjSource instanceof ActivityRecord) {
13990                        ActivityRecord r = (ActivityRecord)app.adjSource;
13991                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13992                    }
13993                    if (app.adjTarget instanceof ComponentName) {
13994                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13995                    }
13996                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13997                    //        + " lru=" + currApp.lru);
13998                    if (runList == null) {
13999                        runList = new ArrayList<>();
14000                    }
14001                    runList.add(currApp);
14002                }
14003            }
14004        }
14005        return runList;
14006    }
14007
14008    @Override
14009    public List<ApplicationInfo> getRunningExternalApplications() {
14010        enforceNotIsolatedCaller("getRunningExternalApplications");
14011        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
14012        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
14013        if (runningApps != null && runningApps.size() > 0) {
14014            Set<String> extList = new HashSet<String>();
14015            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
14016                if (app.pkgList != null) {
14017                    for (String pkg : app.pkgList) {
14018                        extList.add(pkg);
14019                    }
14020                }
14021            }
14022            IPackageManager pm = AppGlobals.getPackageManager();
14023            for (String pkg : extList) {
14024                try {
14025                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
14026                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
14027                        retList.add(info);
14028                    }
14029                } catch (RemoteException e) {
14030                }
14031            }
14032        }
14033        return retList;
14034    }
14035
14036    @Override
14037    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
14038        enforceNotIsolatedCaller("getMyMemoryState");
14039        synchronized (this) {
14040            ProcessRecord proc;
14041            synchronized (mPidsSelfLocked) {
14042                proc = mPidsSelfLocked.get(Binder.getCallingPid());
14043            }
14044            fillInProcMemInfo(proc, outInfo);
14045        }
14046    }
14047
14048    @Override
14049    public int getMemoryTrimLevel() {
14050        enforceNotIsolatedCaller("getMyMemoryState");
14051        synchronized (this) {
14052            return mLastMemoryLevel;
14053        }
14054    }
14055
14056    @Override
14057    public void onShellCommand(FileDescriptor in, FileDescriptor out,
14058            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
14059        (new ActivityManagerShellCommand(this, false)).exec(
14060                this, in, out, err, args, resultReceiver);
14061    }
14062
14063    @Override
14064    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
14065        if (checkCallingPermission(android.Manifest.permission.DUMP)
14066                != PackageManager.PERMISSION_GRANTED) {
14067            pw.println("Permission Denial: can't dump ActivityManager from from pid="
14068                    + Binder.getCallingPid()
14069                    + ", uid=" + Binder.getCallingUid()
14070                    + " without permission "
14071                    + android.Manifest.permission.DUMP);
14072            return;
14073        }
14074
14075        boolean dumpAll = false;
14076        boolean dumpClient = false;
14077        boolean dumpCheckin = false;
14078        boolean dumpCheckinFormat = false;
14079        String dumpPackage = null;
14080
14081        int opti = 0;
14082        while (opti < args.length) {
14083            String opt = args[opti];
14084            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14085                break;
14086            }
14087            opti++;
14088            if ("-a".equals(opt)) {
14089                dumpAll = true;
14090            } else if ("-c".equals(opt)) {
14091                dumpClient = true;
14092            } else if ("-p".equals(opt)) {
14093                if (opti < args.length) {
14094                    dumpPackage = args[opti];
14095                    opti++;
14096                } else {
14097                    pw.println("Error: -p option requires package argument");
14098                    return;
14099                }
14100                dumpClient = true;
14101            } else if ("--checkin".equals(opt)) {
14102                dumpCheckin = dumpCheckinFormat = true;
14103            } else if ("-C".equals(opt)) {
14104                dumpCheckinFormat = true;
14105            } else if ("-h".equals(opt)) {
14106                ActivityManagerShellCommand.dumpHelp(pw, true);
14107                return;
14108            } else {
14109                pw.println("Unknown argument: " + opt + "; use -h for help");
14110            }
14111        }
14112
14113        long origId = Binder.clearCallingIdentity();
14114        boolean more = false;
14115        // Is the caller requesting to dump a particular piece of data?
14116        if (opti < args.length) {
14117            String cmd = args[opti];
14118            opti++;
14119            if ("activities".equals(cmd) || "a".equals(cmd)) {
14120                synchronized (this) {
14121                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14122                }
14123            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
14124                synchronized (this) {
14125                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
14126                }
14127            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
14128                String[] newArgs;
14129                String name;
14130                if (opti >= args.length) {
14131                    name = null;
14132                    newArgs = EMPTY_STRING_ARRAY;
14133                } else {
14134                    dumpPackage = args[opti];
14135                    opti++;
14136                    newArgs = new String[args.length - opti];
14137                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14138                            args.length - opti);
14139                }
14140                synchronized (this) {
14141                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
14142                }
14143            } else if ("broadcast-stats".equals(cmd)) {
14144                String[] newArgs;
14145                String name;
14146                if (opti >= args.length) {
14147                    name = null;
14148                    newArgs = EMPTY_STRING_ARRAY;
14149                } else {
14150                    dumpPackage = args[opti];
14151                    opti++;
14152                    newArgs = new String[args.length - opti];
14153                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14154                            args.length - opti);
14155                }
14156                synchronized (this) {
14157                    if (dumpCheckinFormat) {
14158                        dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
14159                                dumpPackage);
14160                    } else {
14161                        dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
14162                    }
14163                }
14164            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
14165                String[] newArgs;
14166                String name;
14167                if (opti >= args.length) {
14168                    name = null;
14169                    newArgs = EMPTY_STRING_ARRAY;
14170                } else {
14171                    dumpPackage = args[opti];
14172                    opti++;
14173                    newArgs = new String[args.length - opti];
14174                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14175                            args.length - opti);
14176                }
14177                synchronized (this) {
14178                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
14179                }
14180            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
14181                String[] newArgs;
14182                String name;
14183                if (opti >= args.length) {
14184                    name = null;
14185                    newArgs = EMPTY_STRING_ARRAY;
14186                } else {
14187                    dumpPackage = args[opti];
14188                    opti++;
14189                    newArgs = new String[args.length - opti];
14190                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14191                            args.length - opti);
14192                }
14193                synchronized (this) {
14194                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
14195                }
14196            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
14197                synchronized (this) {
14198                    dumpOomLocked(fd, pw, args, opti, true);
14199                }
14200            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
14201                synchronized (this) {
14202                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
14203                }
14204            } else if ("provider".equals(cmd)) {
14205                String[] newArgs;
14206                String name;
14207                if (opti >= args.length) {
14208                    name = null;
14209                    newArgs = EMPTY_STRING_ARRAY;
14210                } else {
14211                    name = args[opti];
14212                    opti++;
14213                    newArgs = new String[args.length - opti];
14214                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14215                }
14216                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
14217                    pw.println("No providers match: " + name);
14218                    pw.println("Use -h for help.");
14219                }
14220            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
14221                synchronized (this) {
14222                    dumpProvidersLocked(fd, pw, args, opti, true, null);
14223                }
14224            } else if ("service".equals(cmd)) {
14225                String[] newArgs;
14226                String name;
14227                if (opti >= args.length) {
14228                    name = null;
14229                    newArgs = EMPTY_STRING_ARRAY;
14230                } else {
14231                    name = args[opti];
14232                    opti++;
14233                    newArgs = new String[args.length - opti];
14234                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14235                            args.length - opti);
14236                }
14237                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
14238                    pw.println("No services match: " + name);
14239                    pw.println("Use -h for help.");
14240                }
14241            } else if ("package".equals(cmd)) {
14242                String[] newArgs;
14243                if (opti >= args.length) {
14244                    pw.println("package: no package name specified");
14245                    pw.println("Use -h for help.");
14246                } else {
14247                    dumpPackage = args[opti];
14248                    opti++;
14249                    newArgs = new String[args.length - opti];
14250                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14251                            args.length - opti);
14252                    args = newArgs;
14253                    opti = 0;
14254                    more = true;
14255                }
14256            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
14257                synchronized (this) {
14258                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14259                }
14260            } else if ("services".equals(cmd) || "s".equals(cmd)) {
14261                if (dumpClient) {
14262                    ActiveServices.ServiceDumper dumper;
14263                    synchronized (this) {
14264                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14265                                dumpPackage);
14266                    }
14267                    dumper.dumpWithClient();
14268                } else {
14269                    synchronized (this) {
14270                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14271                                dumpPackage).dumpLocked();
14272                    }
14273                }
14274            } else if ("locks".equals(cmd)) {
14275                LockGuard.dump(fd, pw, args);
14276            } else {
14277                // Dumping a single activity?
14278                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
14279                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
14280                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
14281                    if (res < 0) {
14282                        pw.println("Bad activity command, or no activities match: " + cmd);
14283                        pw.println("Use -h for help.");
14284                    }
14285                }
14286            }
14287            if (!more) {
14288                Binder.restoreCallingIdentity(origId);
14289                return;
14290            }
14291        }
14292
14293        // No piece of data specified, dump everything.
14294        if (dumpCheckinFormat) {
14295            dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
14296        } else if (dumpClient) {
14297            ActiveServices.ServiceDumper sdumper;
14298            synchronized (this) {
14299                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14300                pw.println();
14301                if (dumpAll) {
14302                    pw.println("-------------------------------------------------------------------------------");
14303                }
14304                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14305                pw.println();
14306                if (dumpAll) {
14307                    pw.println("-------------------------------------------------------------------------------");
14308                }
14309                if (dumpAll || dumpPackage != null) {
14310                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14311                    pw.println();
14312                    if (dumpAll) {
14313                        pw.println("-------------------------------------------------------------------------------");
14314                    }
14315                }
14316                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14317                pw.println();
14318                if (dumpAll) {
14319                    pw.println("-------------------------------------------------------------------------------");
14320                }
14321                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14322                pw.println();
14323                if (dumpAll) {
14324                    pw.println("-------------------------------------------------------------------------------");
14325                }
14326                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
14327                        dumpPackage);
14328            }
14329            sdumper.dumpWithClient();
14330            pw.println();
14331            synchronized (this) {
14332                if (dumpAll) {
14333                    pw.println("-------------------------------------------------------------------------------");
14334                }
14335                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14336                pw.println();
14337                if (dumpAll) {
14338                    pw.println("-------------------------------------------------------------------------------");
14339                }
14340                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14341                if (mAssociations.size() > 0) {
14342                    pw.println();
14343                    if (dumpAll) {
14344                        pw.println("-------------------------------------------------------------------------------");
14345                    }
14346                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14347                }
14348                pw.println();
14349                if (dumpAll) {
14350                    pw.println("-------------------------------------------------------------------------------");
14351                }
14352                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14353            }
14354
14355        } else {
14356            synchronized (this) {
14357                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14358                pw.println();
14359                if (dumpAll) {
14360                    pw.println("-------------------------------------------------------------------------------");
14361                }
14362                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14363                pw.println();
14364                if (dumpAll) {
14365                    pw.println("-------------------------------------------------------------------------------");
14366                }
14367                if (dumpAll || dumpPackage != null) {
14368                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14369                    pw.println();
14370                    if (dumpAll) {
14371                        pw.println("-------------------------------------------------------------------------------");
14372                    }
14373                }
14374                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14375                pw.println();
14376                if (dumpAll) {
14377                    pw.println("-------------------------------------------------------------------------------");
14378                }
14379                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14380                pw.println();
14381                if (dumpAll) {
14382                    pw.println("-------------------------------------------------------------------------------");
14383                }
14384                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
14385                        .dumpLocked();
14386                pw.println();
14387                if (dumpAll) {
14388                    pw.println("-------------------------------------------------------------------------------");
14389                }
14390                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14391                pw.println();
14392                if (dumpAll) {
14393                    pw.println("-------------------------------------------------------------------------------");
14394                }
14395                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14396                if (mAssociations.size() > 0) {
14397                    pw.println();
14398                    if (dumpAll) {
14399                        pw.println("-------------------------------------------------------------------------------");
14400                    }
14401                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14402                }
14403                pw.println();
14404                if (dumpAll) {
14405                    pw.println("-------------------------------------------------------------------------------");
14406                }
14407                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14408            }
14409        }
14410        Binder.restoreCallingIdentity(origId);
14411    }
14412
14413    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14414            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14415        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
14416
14417        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
14418                dumpPackage);
14419        boolean needSep = printedAnything;
14420
14421        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
14422                dumpPackage, needSep, "  mFocusedActivity: ");
14423        if (printed) {
14424            printedAnything = true;
14425            needSep = false;
14426        }
14427
14428        if (dumpPackage == null) {
14429            if (needSep) {
14430                pw.println();
14431            }
14432            needSep = true;
14433            printedAnything = true;
14434            mStackSupervisor.dump(pw, "  ");
14435        }
14436
14437        if (!printedAnything) {
14438            pw.println("  (nothing)");
14439        }
14440    }
14441
14442    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14443            int opti, boolean dumpAll, String dumpPackage) {
14444        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14445
14446        boolean printedAnything = false;
14447
14448        if (mRecentTasks != null && mRecentTasks.size() > 0) {
14449            boolean printedHeader = false;
14450
14451            final int N = mRecentTasks.size();
14452            for (int i=0; i<N; i++) {
14453                TaskRecord tr = mRecentTasks.get(i);
14454                if (dumpPackage != null) {
14455                    if (tr.realActivity == null ||
14456                            !dumpPackage.equals(tr.realActivity)) {
14457                        continue;
14458                    }
14459                }
14460                if (!printedHeader) {
14461                    pw.println("  Recent tasks:");
14462                    printedHeader = true;
14463                    printedAnything = true;
14464                }
14465                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
14466                        pw.println(tr);
14467                if (dumpAll) {
14468                    mRecentTasks.get(i).dump(pw, "    ");
14469                }
14470            }
14471        }
14472
14473        if (!printedAnything) {
14474            pw.println("  (nothing)");
14475        }
14476    }
14477
14478    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14479            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14480        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14481
14482        int dumpUid = 0;
14483        if (dumpPackage != null) {
14484            IPackageManager pm = AppGlobals.getPackageManager();
14485            try {
14486                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
14487            } catch (RemoteException e) {
14488            }
14489        }
14490
14491        boolean printedAnything = false;
14492
14493        final long now = SystemClock.uptimeMillis();
14494
14495        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14496            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14497                    = mAssociations.valueAt(i1);
14498            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14499                SparseArray<ArrayMap<String, Association>> sourceUids
14500                        = targetComponents.valueAt(i2);
14501                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14502                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14503                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14504                        Association ass = sourceProcesses.valueAt(i4);
14505                        if (dumpPackage != null) {
14506                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14507                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14508                                continue;
14509                            }
14510                        }
14511                        printedAnything = true;
14512                        pw.print("  ");
14513                        pw.print(ass.mTargetProcess);
14514                        pw.print("/");
14515                        UserHandle.formatUid(pw, ass.mTargetUid);
14516                        pw.print(" <- ");
14517                        pw.print(ass.mSourceProcess);
14518                        pw.print("/");
14519                        UserHandle.formatUid(pw, ass.mSourceUid);
14520                        pw.println();
14521                        pw.print("    via ");
14522                        pw.print(ass.mTargetComponent.flattenToShortString());
14523                        pw.println();
14524                        pw.print("    ");
14525                        long dur = ass.mTime;
14526                        if (ass.mNesting > 0) {
14527                            dur += now - ass.mStartTime;
14528                        }
14529                        TimeUtils.formatDuration(dur, pw);
14530                        pw.print(" (");
14531                        pw.print(ass.mCount);
14532                        pw.print(" times)");
14533                        pw.print("  ");
14534                        for (int i=0; i<ass.mStateTimes.length; i++) {
14535                            long amt = ass.mStateTimes[i];
14536                            if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14537                                amt += now - ass.mLastStateUptime;
14538                            }
14539                            if (amt != 0) {
14540                                pw.print(" ");
14541                                pw.print(ProcessList.makeProcStateString(
14542                                            i + ActivityManager.MIN_PROCESS_STATE));
14543                                pw.print("=");
14544                                TimeUtils.formatDuration(amt, pw);
14545                                if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14546                                    pw.print("*");
14547                                }
14548                            }
14549                        }
14550                        pw.println();
14551                        if (ass.mNesting > 0) {
14552                            pw.print("    Currently active: ");
14553                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
14554                            pw.println();
14555                        }
14556                    }
14557                }
14558            }
14559
14560        }
14561
14562        if (!printedAnything) {
14563            pw.println("  (nothing)");
14564        }
14565    }
14566
14567    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14568            String header, boolean needSep) {
14569        boolean printed = false;
14570        int whichAppId = -1;
14571        if (dumpPackage != null) {
14572            try {
14573                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14574                        dumpPackage, 0);
14575                whichAppId = UserHandle.getAppId(info.uid);
14576            } catch (NameNotFoundException e) {
14577                e.printStackTrace();
14578            }
14579        }
14580        for (int i=0; i<uids.size(); i++) {
14581            UidRecord uidRec = uids.valueAt(i);
14582            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14583                continue;
14584            }
14585            if (!printed) {
14586                printed = true;
14587                if (needSep) {
14588                    pw.println();
14589                }
14590                pw.print("  ");
14591                pw.println(header);
14592                needSep = true;
14593            }
14594            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14595            pw.print(": "); pw.println(uidRec);
14596        }
14597        return printed;
14598    }
14599
14600    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14601            int opti, boolean dumpAll, String dumpPackage) {
14602        boolean needSep = false;
14603        boolean printedAnything = false;
14604        int numPers = 0;
14605
14606        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14607
14608        if (dumpAll) {
14609            final int NP = mProcessNames.getMap().size();
14610            for (int ip=0; ip<NP; ip++) {
14611                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14612                final int NA = procs.size();
14613                for (int ia=0; ia<NA; ia++) {
14614                    ProcessRecord r = procs.valueAt(ia);
14615                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14616                        continue;
14617                    }
14618                    if (!needSep) {
14619                        pw.println("  All known processes:");
14620                        needSep = true;
14621                        printedAnything = true;
14622                    }
14623                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14624                        pw.print(" UID "); pw.print(procs.keyAt(ia));
14625                        pw.print(" "); pw.println(r);
14626                    r.dump(pw, "    ");
14627                    if (r.persistent) {
14628                        numPers++;
14629                    }
14630                }
14631            }
14632        }
14633
14634        if (mIsolatedProcesses.size() > 0) {
14635            boolean printed = false;
14636            for (int i=0; i<mIsolatedProcesses.size(); i++) {
14637                ProcessRecord r = mIsolatedProcesses.valueAt(i);
14638                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14639                    continue;
14640                }
14641                if (!printed) {
14642                    if (needSep) {
14643                        pw.println();
14644                    }
14645                    pw.println("  Isolated process list (sorted by uid):");
14646                    printedAnything = true;
14647                    printed = true;
14648                    needSep = true;
14649                }
14650                pw.println(String.format("%sIsolated #%2d: %s",
14651                        "    ", i, r.toString()));
14652            }
14653        }
14654
14655        if (mActiveUids.size() > 0) {
14656            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14657                printedAnything = needSep = true;
14658            }
14659        }
14660        if (mValidateUids.size() > 0) {
14661            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14662                printedAnything = needSep = true;
14663            }
14664        }
14665
14666        if (mLruProcesses.size() > 0) {
14667            if (needSep) {
14668                pw.println();
14669            }
14670            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14671                    pw.print(" total, non-act at ");
14672                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14673                    pw.print(", non-svc at ");
14674                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14675                    pw.println("):");
14676            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14677            needSep = true;
14678            printedAnything = true;
14679        }
14680
14681        if (dumpAll || dumpPackage != null) {
14682            synchronized (mPidsSelfLocked) {
14683                boolean printed = false;
14684                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14685                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14686                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14687                        continue;
14688                    }
14689                    if (!printed) {
14690                        if (needSep) pw.println();
14691                        needSep = true;
14692                        pw.println("  PID mappings:");
14693                        printed = true;
14694                        printedAnything = true;
14695                    }
14696                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14697                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14698                }
14699            }
14700        }
14701
14702        if (mForegroundProcesses.size() > 0) {
14703            synchronized (mPidsSelfLocked) {
14704                boolean printed = false;
14705                for (int i=0; i<mForegroundProcesses.size(); i++) {
14706                    ProcessRecord r = mPidsSelfLocked.get(
14707                            mForegroundProcesses.valueAt(i).pid);
14708                    if (dumpPackage != null && (r == null
14709                            || !r.pkgList.containsKey(dumpPackage))) {
14710                        continue;
14711                    }
14712                    if (!printed) {
14713                        if (needSep) pw.println();
14714                        needSep = true;
14715                        pw.println("  Foreground Processes:");
14716                        printed = true;
14717                        printedAnything = true;
14718                    }
14719                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14720                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14721                }
14722            }
14723        }
14724
14725        if (mPersistentStartingProcesses.size() > 0) {
14726            if (needSep) pw.println();
14727            needSep = true;
14728            printedAnything = true;
14729            pw.println("  Persisent processes that are starting:");
14730            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14731                    "Starting Norm", "Restarting PERS", dumpPackage);
14732        }
14733
14734        if (mRemovedProcesses.size() > 0) {
14735            if (needSep) pw.println();
14736            needSep = true;
14737            printedAnything = true;
14738            pw.println("  Processes that are being removed:");
14739            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14740                    "Removed Norm", "Removed PERS", dumpPackage);
14741        }
14742
14743        if (mProcessesOnHold.size() > 0) {
14744            if (needSep) pw.println();
14745            needSep = true;
14746            printedAnything = true;
14747            pw.println("  Processes that are on old until the system is ready:");
14748            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14749                    "OnHold Norm", "OnHold PERS", dumpPackage);
14750        }
14751
14752        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14753
14754        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14755        if (needSep) {
14756            printedAnything = true;
14757        }
14758
14759        if (dumpPackage == null) {
14760            pw.println();
14761            needSep = false;
14762            mUserController.dump(pw, dumpAll);
14763        }
14764        if (mHomeProcess != null && (dumpPackage == null
14765                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14766            if (needSep) {
14767                pw.println();
14768                needSep = false;
14769            }
14770            pw.println("  mHomeProcess: " + mHomeProcess);
14771        }
14772        if (mPreviousProcess != null && (dumpPackage == null
14773                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14774            if (needSep) {
14775                pw.println();
14776                needSep = false;
14777            }
14778            pw.println("  mPreviousProcess: " + mPreviousProcess);
14779        }
14780        if (dumpAll) {
14781            StringBuilder sb = new StringBuilder(128);
14782            sb.append("  mPreviousProcessVisibleTime: ");
14783            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14784            pw.println(sb);
14785        }
14786        if (mHeavyWeightProcess != null && (dumpPackage == null
14787                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14788            if (needSep) {
14789                pw.println();
14790                needSep = false;
14791            }
14792            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14793        }
14794        if (dumpPackage == null) {
14795            pw.println("  mConfiguration: " + mConfiguration);
14796        }
14797        if (dumpAll) {
14798            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14799            if (mCompatModePackages.getPackages().size() > 0) {
14800                boolean printed = false;
14801                for (Map.Entry<String, Integer> entry
14802                        : mCompatModePackages.getPackages().entrySet()) {
14803                    String pkg = entry.getKey();
14804                    int mode = entry.getValue();
14805                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14806                        continue;
14807                    }
14808                    if (!printed) {
14809                        pw.println("  mScreenCompatPackages:");
14810                        printed = true;
14811                    }
14812                    pw.print("    "); pw.print(pkg); pw.print(": ");
14813                            pw.print(mode); pw.println();
14814                }
14815            }
14816        }
14817        if (dumpPackage == null) {
14818            pw.println("  mWakefulness="
14819                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14820            pw.println("  mSleepTokens=" + mSleepTokens);
14821            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14822                    + lockScreenShownToString());
14823            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14824            if (mRunningVoice != null) {
14825                pw.println("  mRunningVoice=" + mRunningVoice);
14826                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14827            }
14828        }
14829        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14830                || mOrigWaitForDebugger) {
14831            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14832                    || dumpPackage.equals(mOrigDebugApp)) {
14833                if (needSep) {
14834                    pw.println();
14835                    needSep = false;
14836                }
14837                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14838                        + " mDebugTransient=" + mDebugTransient
14839                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14840            }
14841        }
14842        if (mCurAppTimeTracker != null) {
14843            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14844        }
14845        if (mMemWatchProcesses.getMap().size() > 0) {
14846            pw.println("  Mem watch processes:");
14847            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14848                    = mMemWatchProcesses.getMap();
14849            for (int i=0; i<procs.size(); i++) {
14850                final String proc = procs.keyAt(i);
14851                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14852                for (int j=0; j<uids.size(); j++) {
14853                    if (needSep) {
14854                        pw.println();
14855                        needSep = false;
14856                    }
14857                    StringBuilder sb = new StringBuilder();
14858                    sb.append("    ").append(proc).append('/');
14859                    UserHandle.formatUid(sb, uids.keyAt(j));
14860                    Pair<Long, String> val = uids.valueAt(j);
14861                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14862                    if (val.second != null) {
14863                        sb.append(", report to ").append(val.second);
14864                    }
14865                    pw.println(sb.toString());
14866                }
14867            }
14868            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14869            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14870            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14871                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14872        }
14873        if (mTrackAllocationApp != null) {
14874            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14875                if (needSep) {
14876                    pw.println();
14877                    needSep = false;
14878                }
14879                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14880            }
14881        }
14882        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14883                || mProfileFd != null) {
14884            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14885                if (needSep) {
14886                    pw.println();
14887                    needSep = false;
14888                }
14889                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14890                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14891                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14892                        + mAutoStopProfiler);
14893                pw.println("  mProfileType=" + mProfileType);
14894            }
14895        }
14896        if (mNativeDebuggingApp != null) {
14897            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14898                if (needSep) {
14899                    pw.println();
14900                    needSep = false;
14901                }
14902                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14903            }
14904        }
14905        if (dumpPackage == null) {
14906            if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14907                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14908                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14909            }
14910            if (mController != null) {
14911                pw.println("  mController=" + mController
14912                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14913            }
14914            if (dumpAll) {
14915                pw.println("  Total persistent processes: " + numPers);
14916                pw.println("  mProcessesReady=" + mProcessesReady
14917                        + " mSystemReady=" + mSystemReady
14918                        + " mBooted=" + mBooted
14919                        + " mFactoryTest=" + mFactoryTest);
14920                pw.println("  mBooting=" + mBooting
14921                        + " mCallFinishBooting=" + mCallFinishBooting
14922                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14923                pw.print("  mLastPowerCheckRealtime=");
14924                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14925                        pw.println("");
14926                pw.print("  mLastPowerCheckUptime=");
14927                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14928                        pw.println("");
14929                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14930                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14931                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14932                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14933                        + " (" + mLruProcesses.size() + " total)"
14934                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14935                        + " mNumServiceProcs=" + mNumServiceProcs
14936                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14937                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14938                        + " mLastMemoryLevel=" + mLastMemoryLevel
14939                        + " mLastNumProcesses=" + mLastNumProcesses);
14940                long now = SystemClock.uptimeMillis();
14941                pw.print("  mLastIdleTime=");
14942                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14943                        pw.print(" mLowRamSinceLastIdle=");
14944                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14945                        pw.println();
14946            }
14947        }
14948
14949        if (!printedAnything) {
14950            pw.println("  (nothing)");
14951        }
14952    }
14953
14954    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14955            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14956        if (mProcessesToGc.size() > 0) {
14957            boolean printed = false;
14958            long now = SystemClock.uptimeMillis();
14959            for (int i=0; i<mProcessesToGc.size(); i++) {
14960                ProcessRecord proc = mProcessesToGc.get(i);
14961                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14962                    continue;
14963                }
14964                if (!printed) {
14965                    if (needSep) pw.println();
14966                    needSep = true;
14967                    pw.println("  Processes that are waiting to GC:");
14968                    printed = true;
14969                }
14970                pw.print("    Process "); pw.println(proc);
14971                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14972                        pw.print(", last gced=");
14973                        pw.print(now-proc.lastRequestedGc);
14974                        pw.print(" ms ago, last lowMem=");
14975                        pw.print(now-proc.lastLowMemory);
14976                        pw.println(" ms ago");
14977
14978            }
14979        }
14980        return needSep;
14981    }
14982
14983    void printOomLevel(PrintWriter pw, String name, int adj) {
14984        pw.print("    ");
14985        if (adj >= 0) {
14986            pw.print(' ');
14987            if (adj < 10) pw.print(' ');
14988        } else {
14989            if (adj > -10) pw.print(' ');
14990        }
14991        pw.print(adj);
14992        pw.print(": ");
14993        pw.print(name);
14994        pw.print(" (");
14995        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14996        pw.println(")");
14997    }
14998
14999    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15000            int opti, boolean dumpAll) {
15001        boolean needSep = false;
15002
15003        if (mLruProcesses.size() > 0) {
15004            if (needSep) pw.println();
15005            needSep = true;
15006            pw.println("  OOM levels:");
15007            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
15008            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
15009            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
15010            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
15011            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
15012            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
15013            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
15014            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
15015            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
15016            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
15017            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
15018            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
15019            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
15020            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
15021
15022            if (needSep) pw.println();
15023            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
15024                    pw.print(" total, non-act at ");
15025                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15026                    pw.print(", non-svc at ");
15027                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15028                    pw.println("):");
15029            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
15030            needSep = true;
15031        }
15032
15033        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
15034
15035        pw.println();
15036        pw.println("  mHomeProcess: " + mHomeProcess);
15037        pw.println("  mPreviousProcess: " + mPreviousProcess);
15038        if (mHeavyWeightProcess != null) {
15039            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
15040        }
15041
15042        return true;
15043    }
15044
15045    /**
15046     * There are three ways to call this:
15047     *  - no provider specified: dump all the providers
15048     *  - a flattened component name that matched an existing provider was specified as the
15049     *    first arg: dump that one provider
15050     *  - the first arg isn't the flattened component name of an existing provider:
15051     *    dump all providers whose component contains the first arg as a substring
15052     */
15053    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15054            int opti, boolean dumpAll) {
15055        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
15056    }
15057
15058    static class ItemMatcher {
15059        ArrayList<ComponentName> components;
15060        ArrayList<String> strings;
15061        ArrayList<Integer> objects;
15062        boolean all;
15063
15064        ItemMatcher() {
15065            all = true;
15066        }
15067
15068        void build(String name) {
15069            ComponentName componentName = ComponentName.unflattenFromString(name);
15070            if (componentName != null) {
15071                if (components == null) {
15072                    components = new ArrayList<ComponentName>();
15073                }
15074                components.add(componentName);
15075                all = false;
15076            } else {
15077                int objectId = 0;
15078                // Not a '/' separated full component name; maybe an object ID?
15079                try {
15080                    objectId = Integer.parseInt(name, 16);
15081                    if (objects == null) {
15082                        objects = new ArrayList<Integer>();
15083                    }
15084                    objects.add(objectId);
15085                    all = false;
15086                } catch (RuntimeException e) {
15087                    // Not an integer; just do string match.
15088                    if (strings == null) {
15089                        strings = new ArrayList<String>();
15090                    }
15091                    strings.add(name);
15092                    all = false;
15093                }
15094            }
15095        }
15096
15097        int build(String[] args, int opti) {
15098            for (; opti<args.length; opti++) {
15099                String name = args[opti];
15100                if ("--".equals(name)) {
15101                    return opti+1;
15102                }
15103                build(name);
15104            }
15105            return opti;
15106        }
15107
15108        boolean match(Object object, ComponentName comp) {
15109            if (all) {
15110                return true;
15111            }
15112            if (components != null) {
15113                for (int i=0; i<components.size(); i++) {
15114                    if (components.get(i).equals(comp)) {
15115                        return true;
15116                    }
15117                }
15118            }
15119            if (objects != null) {
15120                for (int i=0; i<objects.size(); i++) {
15121                    if (System.identityHashCode(object) == objects.get(i)) {
15122                        return true;
15123                    }
15124                }
15125            }
15126            if (strings != null) {
15127                String flat = comp.flattenToString();
15128                for (int i=0; i<strings.size(); i++) {
15129                    if (flat.contains(strings.get(i))) {
15130                        return true;
15131                    }
15132                }
15133            }
15134            return false;
15135        }
15136    }
15137
15138    /**
15139     * There are three things that cmd can be:
15140     *  - a flattened component name that matches an existing activity
15141     *  - the cmd arg isn't the flattened component name of an existing activity:
15142     *    dump all activity whose component contains the cmd as a substring
15143     *  - A hex number of the ActivityRecord object instance.
15144     */
15145    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15146            int opti, boolean dumpAll) {
15147        ArrayList<ActivityRecord> activities;
15148
15149        synchronized (this) {
15150            activities = mStackSupervisor.getDumpActivitiesLocked(name);
15151        }
15152
15153        if (activities.size() <= 0) {
15154            return false;
15155        }
15156
15157        String[] newArgs = new String[args.length - opti];
15158        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15159
15160        TaskRecord lastTask = null;
15161        boolean needSep = false;
15162        for (int i=activities.size()-1; i>=0; i--) {
15163            ActivityRecord r = activities.get(i);
15164            if (needSep) {
15165                pw.println();
15166            }
15167            needSep = true;
15168            synchronized (this) {
15169                if (lastTask != r.task) {
15170                    lastTask = r.task;
15171                    pw.print("TASK "); pw.print(lastTask.affinity);
15172                            pw.print(" id="); pw.println(lastTask.taskId);
15173                    if (dumpAll) {
15174                        lastTask.dump(pw, "  ");
15175                    }
15176                }
15177            }
15178            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
15179        }
15180        return true;
15181    }
15182
15183    /**
15184     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
15185     * there is a thread associated with the activity.
15186     */
15187    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
15188            final ActivityRecord r, String[] args, boolean dumpAll) {
15189        String innerPrefix = prefix + "  ";
15190        synchronized (this) {
15191            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
15192                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
15193                    pw.print(" pid=");
15194                    if (r.app != null) pw.println(r.app.pid);
15195                    else pw.println("(not running)");
15196            if (dumpAll) {
15197                r.dump(pw, innerPrefix);
15198            }
15199        }
15200        if (r.app != null && r.app.thread != null) {
15201            // flush anything that is already in the PrintWriter since the thread is going
15202            // to write to the file descriptor directly
15203            pw.flush();
15204            try {
15205                TransferPipe tp = new TransferPipe();
15206                try {
15207                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
15208                            r.appToken, innerPrefix, args);
15209                    tp.go(fd);
15210                } finally {
15211                    tp.kill();
15212                }
15213            } catch (IOException e) {
15214                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
15215            } catch (RemoteException e) {
15216                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
15217            }
15218        }
15219    }
15220
15221    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15222            int opti, boolean dumpAll, String dumpPackage) {
15223        boolean needSep = false;
15224        boolean onlyHistory = false;
15225        boolean printedAnything = false;
15226
15227        if ("history".equals(dumpPackage)) {
15228            if (opti < args.length && "-s".equals(args[opti])) {
15229                dumpAll = false;
15230            }
15231            onlyHistory = true;
15232            dumpPackage = null;
15233        }
15234
15235        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
15236        if (!onlyHistory && dumpAll) {
15237            if (mRegisteredReceivers.size() > 0) {
15238                boolean printed = false;
15239                Iterator it = mRegisteredReceivers.values().iterator();
15240                while (it.hasNext()) {
15241                    ReceiverList r = (ReceiverList)it.next();
15242                    if (dumpPackage != null && (r.app == null ||
15243                            !dumpPackage.equals(r.app.info.packageName))) {
15244                        continue;
15245                    }
15246                    if (!printed) {
15247                        pw.println("  Registered Receivers:");
15248                        needSep = true;
15249                        printed = true;
15250                        printedAnything = true;
15251                    }
15252                    pw.print("  * "); pw.println(r);
15253                    r.dump(pw, "    ");
15254                }
15255            }
15256
15257            if (mReceiverResolver.dump(pw, needSep ?
15258                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
15259                    "    ", dumpPackage, false, false)) {
15260                needSep = true;
15261                printedAnything = true;
15262            }
15263        }
15264
15265        for (BroadcastQueue q : mBroadcastQueues) {
15266            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
15267            printedAnything |= needSep;
15268        }
15269
15270        needSep = true;
15271
15272        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
15273            for (int user=0; user<mStickyBroadcasts.size(); user++) {
15274                if (needSep) {
15275                    pw.println();
15276                }
15277                needSep = true;
15278                printedAnything = true;
15279                pw.print("  Sticky broadcasts for user ");
15280                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
15281                StringBuilder sb = new StringBuilder(128);
15282                for (Map.Entry<String, ArrayList<Intent>> ent
15283                        : mStickyBroadcasts.valueAt(user).entrySet()) {
15284                    pw.print("  * Sticky action "); pw.print(ent.getKey());
15285                    if (dumpAll) {
15286                        pw.println(":");
15287                        ArrayList<Intent> intents = ent.getValue();
15288                        final int N = intents.size();
15289                        for (int i=0; i<N; i++) {
15290                            sb.setLength(0);
15291                            sb.append("    Intent: ");
15292                            intents.get(i).toShortString(sb, false, true, false, false);
15293                            pw.println(sb.toString());
15294                            Bundle bundle = intents.get(i).getExtras();
15295                            if (bundle != null) {
15296                                pw.print("      ");
15297                                pw.println(bundle.toString());
15298                            }
15299                        }
15300                    } else {
15301                        pw.println("");
15302                    }
15303                }
15304            }
15305        }
15306
15307        if (!onlyHistory && dumpAll) {
15308            pw.println();
15309            for (BroadcastQueue queue : mBroadcastQueues) {
15310                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
15311                        + queue.mBroadcastsScheduled);
15312            }
15313            pw.println("  mHandler:");
15314            mHandler.dump(new PrintWriterPrinter(pw), "    ");
15315            needSep = true;
15316            printedAnything = true;
15317        }
15318
15319        if (!printedAnything) {
15320            pw.println("  (nothing)");
15321        }
15322    }
15323
15324    void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15325            int opti, boolean dumpAll, String dumpPackage) {
15326        if (mCurBroadcastStats == null) {
15327            return;
15328        }
15329
15330        pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
15331        final long now = SystemClock.elapsedRealtime();
15332        if (mLastBroadcastStats != null) {
15333            pw.print("  Last stats (from ");
15334            TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
15335            pw.print(" to ");
15336            TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
15337            pw.print(", ");
15338            TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
15339                    - mLastBroadcastStats.mStartUptime, pw);
15340            pw.println(" uptime):");
15341            if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15342                pw.println("    (nothing)");
15343            }
15344            pw.println();
15345        }
15346        pw.print("  Current stats (from ");
15347        TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
15348        pw.print(" to now, ");
15349        TimeUtils.formatDuration(SystemClock.uptimeMillis()
15350                - mCurBroadcastStats.mStartUptime, pw);
15351        pw.println(" uptime):");
15352        if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15353            pw.println("    (nothing)");
15354        }
15355    }
15356
15357    void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15358            int opti, boolean fullCheckin, String dumpPackage) {
15359        if (mCurBroadcastStats == null) {
15360            return;
15361        }
15362
15363        if (mLastBroadcastStats != null) {
15364            mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15365            if (fullCheckin) {
15366                mLastBroadcastStats = null;
15367                return;
15368            }
15369        }
15370        mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15371        if (fullCheckin) {
15372            mCurBroadcastStats = null;
15373        }
15374    }
15375
15376    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15377            int opti, boolean dumpAll, String dumpPackage) {
15378        boolean needSep;
15379        boolean printedAnything = false;
15380
15381        ItemMatcher matcher = new ItemMatcher();
15382        matcher.build(args, opti);
15383
15384        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
15385
15386        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
15387        printedAnything |= needSep;
15388
15389        if (mLaunchingProviders.size() > 0) {
15390            boolean printed = false;
15391            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
15392                ContentProviderRecord r = mLaunchingProviders.get(i);
15393                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
15394                    continue;
15395                }
15396                if (!printed) {
15397                    if (needSep) pw.println();
15398                    needSep = true;
15399                    pw.println("  Launching content providers:");
15400                    printed = true;
15401                    printedAnything = true;
15402                }
15403                pw.print("  Launching #"); pw.print(i); pw.print(": ");
15404                        pw.println(r);
15405            }
15406        }
15407
15408        if (!printedAnything) {
15409            pw.println("  (nothing)");
15410        }
15411    }
15412
15413    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15414            int opti, boolean dumpAll, String dumpPackage) {
15415        boolean needSep = false;
15416        boolean printedAnything = false;
15417
15418        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
15419
15420        if (mGrantedUriPermissions.size() > 0) {
15421            boolean printed = false;
15422            int dumpUid = -2;
15423            if (dumpPackage != null) {
15424                try {
15425                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
15426                            MATCH_UNINSTALLED_PACKAGES, 0);
15427                } catch (NameNotFoundException e) {
15428                    dumpUid = -1;
15429                }
15430            }
15431            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
15432                int uid = mGrantedUriPermissions.keyAt(i);
15433                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
15434                    continue;
15435                }
15436                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
15437                if (!printed) {
15438                    if (needSep) pw.println();
15439                    needSep = true;
15440                    pw.println("  Granted Uri Permissions:");
15441                    printed = true;
15442                    printedAnything = true;
15443                }
15444                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
15445                for (UriPermission perm : perms.values()) {
15446                    pw.print("    "); pw.println(perm);
15447                    if (dumpAll) {
15448                        perm.dump(pw, "      ");
15449                    }
15450                }
15451            }
15452        }
15453
15454        if (!printedAnything) {
15455            pw.println("  (nothing)");
15456        }
15457    }
15458
15459    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15460            int opti, boolean dumpAll, String dumpPackage) {
15461        boolean printed = false;
15462
15463        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
15464
15465        if (mIntentSenderRecords.size() > 0) {
15466            Iterator<WeakReference<PendingIntentRecord>> it
15467                    = mIntentSenderRecords.values().iterator();
15468            while (it.hasNext()) {
15469                WeakReference<PendingIntentRecord> ref = it.next();
15470                PendingIntentRecord rec = ref != null ? ref.get(): null;
15471                if (dumpPackage != null && (rec == null
15472                        || !dumpPackage.equals(rec.key.packageName))) {
15473                    continue;
15474                }
15475                printed = true;
15476                if (rec != null) {
15477                    pw.print("  * "); pw.println(rec);
15478                    if (dumpAll) {
15479                        rec.dump(pw, "    ");
15480                    }
15481                } else {
15482                    pw.print("  * "); pw.println(ref);
15483                }
15484            }
15485        }
15486
15487        if (!printed) {
15488            pw.println("  (nothing)");
15489        }
15490    }
15491
15492    private static final int dumpProcessList(PrintWriter pw,
15493            ActivityManagerService service, List list,
15494            String prefix, String normalLabel, String persistentLabel,
15495            String dumpPackage) {
15496        int numPers = 0;
15497        final int N = list.size()-1;
15498        for (int i=N; i>=0; i--) {
15499            ProcessRecord r = (ProcessRecord)list.get(i);
15500            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15501                continue;
15502            }
15503            pw.println(String.format("%s%s #%2d: %s",
15504                    prefix, (r.persistent ? persistentLabel : normalLabel),
15505                    i, r.toString()));
15506            if (r.persistent) {
15507                numPers++;
15508            }
15509        }
15510        return numPers;
15511    }
15512
15513    private static final boolean dumpProcessOomList(PrintWriter pw,
15514            ActivityManagerService service, List<ProcessRecord> origList,
15515            String prefix, String normalLabel, String persistentLabel,
15516            boolean inclDetails, String dumpPackage) {
15517
15518        ArrayList<Pair<ProcessRecord, Integer>> list
15519                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15520        for (int i=0; i<origList.size(); i++) {
15521            ProcessRecord r = origList.get(i);
15522            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15523                continue;
15524            }
15525            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15526        }
15527
15528        if (list.size() <= 0) {
15529            return false;
15530        }
15531
15532        Comparator<Pair<ProcessRecord, Integer>> comparator
15533                = new Comparator<Pair<ProcessRecord, Integer>>() {
15534            @Override
15535            public int compare(Pair<ProcessRecord, Integer> object1,
15536                    Pair<ProcessRecord, Integer> object2) {
15537                if (object1.first.setAdj != object2.first.setAdj) {
15538                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15539                }
15540                if (object1.first.setProcState != object2.first.setProcState) {
15541                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15542                }
15543                if (object1.second.intValue() != object2.second.intValue()) {
15544                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15545                }
15546                return 0;
15547            }
15548        };
15549
15550        Collections.sort(list, comparator);
15551
15552        final long curRealtime = SystemClock.elapsedRealtime();
15553        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15554        final long curUptime = SystemClock.uptimeMillis();
15555        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15556
15557        for (int i=list.size()-1; i>=0; i--) {
15558            ProcessRecord r = list.get(i).first;
15559            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15560            char schedGroup;
15561            switch (r.setSchedGroup) {
15562                case ProcessList.SCHED_GROUP_BACKGROUND:
15563                    schedGroup = 'B';
15564                    break;
15565                case ProcessList.SCHED_GROUP_DEFAULT:
15566                    schedGroup = 'F';
15567                    break;
15568                case ProcessList.SCHED_GROUP_TOP_APP:
15569                    schedGroup = 'T';
15570                    break;
15571                default:
15572                    schedGroup = '?';
15573                    break;
15574            }
15575            char foreground;
15576            if (r.foregroundActivities) {
15577                foreground = 'A';
15578            } else if (r.foregroundServices) {
15579                foreground = 'S';
15580            } else {
15581                foreground = ' ';
15582            }
15583            String procState = ProcessList.makeProcStateString(r.curProcState);
15584            pw.print(prefix);
15585            pw.print(r.persistent ? persistentLabel : normalLabel);
15586            pw.print(" #");
15587            int num = (origList.size()-1)-list.get(i).second;
15588            if (num < 10) pw.print(' ');
15589            pw.print(num);
15590            pw.print(": ");
15591            pw.print(oomAdj);
15592            pw.print(' ');
15593            pw.print(schedGroup);
15594            pw.print('/');
15595            pw.print(foreground);
15596            pw.print('/');
15597            pw.print(procState);
15598            pw.print(" trm:");
15599            if (r.trimMemoryLevel < 10) pw.print(' ');
15600            pw.print(r.trimMemoryLevel);
15601            pw.print(' ');
15602            pw.print(r.toShortString());
15603            pw.print(" (");
15604            pw.print(r.adjType);
15605            pw.println(')');
15606            if (r.adjSource != null || r.adjTarget != null) {
15607                pw.print(prefix);
15608                pw.print("    ");
15609                if (r.adjTarget instanceof ComponentName) {
15610                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15611                } else if (r.adjTarget != null) {
15612                    pw.print(r.adjTarget.toString());
15613                } else {
15614                    pw.print("{null}");
15615                }
15616                pw.print("<=");
15617                if (r.adjSource instanceof ProcessRecord) {
15618                    pw.print("Proc{");
15619                    pw.print(((ProcessRecord)r.adjSource).toShortString());
15620                    pw.println("}");
15621                } else if (r.adjSource != null) {
15622                    pw.println(r.adjSource.toString());
15623                } else {
15624                    pw.println("{null}");
15625                }
15626            }
15627            if (inclDetails) {
15628                pw.print(prefix);
15629                pw.print("    ");
15630                pw.print("oom: max="); pw.print(r.maxAdj);
15631                pw.print(" curRaw="); pw.print(r.curRawAdj);
15632                pw.print(" setRaw="); pw.print(r.setRawAdj);
15633                pw.print(" cur="); pw.print(r.curAdj);
15634                pw.print(" set="); pw.println(r.setAdj);
15635                pw.print(prefix);
15636                pw.print("    ");
15637                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15638                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15639                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15640                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15641                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15642                pw.println();
15643                pw.print(prefix);
15644                pw.print("    ");
15645                pw.print("cached="); pw.print(r.cached);
15646                pw.print(" empty="); pw.print(r.empty);
15647                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15648
15649                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15650                    if (r.lastWakeTime != 0) {
15651                        long wtime;
15652                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15653                        synchronized (stats) {
15654                            wtime = stats.getProcessWakeTime(r.info.uid,
15655                                    r.pid, curRealtime);
15656                        }
15657                        long timeUsed = wtime - r.lastWakeTime;
15658                        pw.print(prefix);
15659                        pw.print("    ");
15660                        pw.print("keep awake over ");
15661                        TimeUtils.formatDuration(realtimeSince, pw);
15662                        pw.print(" used ");
15663                        TimeUtils.formatDuration(timeUsed, pw);
15664                        pw.print(" (");
15665                        pw.print((timeUsed*100)/realtimeSince);
15666                        pw.println("%)");
15667                    }
15668                    if (r.lastCpuTime != 0) {
15669                        long timeUsed = r.curCpuTime - r.lastCpuTime;
15670                        pw.print(prefix);
15671                        pw.print("    ");
15672                        pw.print("run cpu over ");
15673                        TimeUtils.formatDuration(uptimeSince, pw);
15674                        pw.print(" used ");
15675                        TimeUtils.formatDuration(timeUsed, pw);
15676                        pw.print(" (");
15677                        pw.print((timeUsed*100)/uptimeSince);
15678                        pw.println("%)");
15679                    }
15680                }
15681            }
15682        }
15683        return true;
15684    }
15685
15686    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15687            String[] args) {
15688        ArrayList<ProcessRecord> procs;
15689        synchronized (this) {
15690            if (args != null && args.length > start
15691                    && args[start].charAt(0) != '-') {
15692                procs = new ArrayList<ProcessRecord>();
15693                int pid = -1;
15694                try {
15695                    pid = Integer.parseInt(args[start]);
15696                } catch (NumberFormatException e) {
15697                }
15698                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15699                    ProcessRecord proc = mLruProcesses.get(i);
15700                    if (proc.pid == pid) {
15701                        procs.add(proc);
15702                    } else if (allPkgs && proc.pkgList != null
15703                            && proc.pkgList.containsKey(args[start])) {
15704                        procs.add(proc);
15705                    } else if (proc.processName.equals(args[start])) {
15706                        procs.add(proc);
15707                    }
15708                }
15709                if (procs.size() <= 0) {
15710                    return null;
15711                }
15712            } else {
15713                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15714            }
15715        }
15716        return procs;
15717    }
15718
15719    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15720            PrintWriter pw, String[] args) {
15721        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15722        if (procs == null) {
15723            pw.println("No process found for: " + args[0]);
15724            return;
15725        }
15726
15727        long uptime = SystemClock.uptimeMillis();
15728        long realtime = SystemClock.elapsedRealtime();
15729        pw.println("Applications Graphics Acceleration Info:");
15730        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15731
15732        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15733            ProcessRecord r = procs.get(i);
15734            if (r.thread != null) {
15735                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15736                pw.flush();
15737                try {
15738                    TransferPipe tp = new TransferPipe();
15739                    try {
15740                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15741                        tp.go(fd);
15742                    } finally {
15743                        tp.kill();
15744                    }
15745                } catch (IOException e) {
15746                    pw.println("Failure while dumping the app: " + r);
15747                    pw.flush();
15748                } catch (RemoteException e) {
15749                    pw.println("Got a RemoteException while dumping the app " + r);
15750                    pw.flush();
15751                }
15752            }
15753        }
15754    }
15755
15756    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15757        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15758        if (procs == null) {
15759            pw.println("No process found for: " + args[0]);
15760            return;
15761        }
15762
15763        pw.println("Applications Database Info:");
15764
15765        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15766            ProcessRecord r = procs.get(i);
15767            if (r.thread != null) {
15768                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15769                pw.flush();
15770                try {
15771                    TransferPipe tp = new TransferPipe();
15772                    try {
15773                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15774                        tp.go(fd);
15775                    } finally {
15776                        tp.kill();
15777                    }
15778                } catch (IOException e) {
15779                    pw.println("Failure while dumping the app: " + r);
15780                    pw.flush();
15781                } catch (RemoteException e) {
15782                    pw.println("Got a RemoteException while dumping the app " + r);
15783                    pw.flush();
15784                }
15785            }
15786        }
15787    }
15788
15789    final static class MemItem {
15790        final boolean isProc;
15791        final String label;
15792        final String shortLabel;
15793        final long pss;
15794        final long swapPss;
15795        final int id;
15796        final boolean hasActivities;
15797        ArrayList<MemItem> subitems;
15798
15799        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15800                boolean _hasActivities) {
15801            isProc = true;
15802            label = _label;
15803            shortLabel = _shortLabel;
15804            pss = _pss;
15805            swapPss = _swapPss;
15806            id = _id;
15807            hasActivities = _hasActivities;
15808        }
15809
15810        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15811            isProc = false;
15812            label = _label;
15813            shortLabel = _shortLabel;
15814            pss = _pss;
15815            swapPss = _swapPss;
15816            id = _id;
15817            hasActivities = false;
15818        }
15819    }
15820
15821    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15822            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15823        if (sort && !isCompact) {
15824            Collections.sort(items, new Comparator<MemItem>() {
15825                @Override
15826                public int compare(MemItem lhs, MemItem rhs) {
15827                    if (lhs.pss < rhs.pss) {
15828                        return 1;
15829                    } else if (lhs.pss > rhs.pss) {
15830                        return -1;
15831                    }
15832                    return 0;
15833                }
15834            });
15835        }
15836
15837        for (int i=0; i<items.size(); i++) {
15838            MemItem mi = items.get(i);
15839            if (!isCompact) {
15840                if (dumpSwapPss) {
15841                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15842                            mi.label, stringifyKBSize(mi.swapPss));
15843                } else {
15844                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15845                }
15846            } else if (mi.isProc) {
15847                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15848                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15849                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15850                pw.println(mi.hasActivities ? ",a" : ",e");
15851            } else {
15852                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15853                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15854            }
15855            if (mi.subitems != null) {
15856                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15857                        true, isCompact, dumpSwapPss);
15858            }
15859        }
15860    }
15861
15862    // These are in KB.
15863    static final long[] DUMP_MEM_BUCKETS = new long[] {
15864        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15865        120*1024, 160*1024, 200*1024,
15866        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15867        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15868    };
15869
15870    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15871            boolean stackLike) {
15872        int start = label.lastIndexOf('.');
15873        if (start >= 0) start++;
15874        else start = 0;
15875        int end = label.length();
15876        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15877            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15878                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15879                out.append(bucket);
15880                out.append(stackLike ? "MB." : "MB ");
15881                out.append(label, start, end);
15882                return;
15883            }
15884        }
15885        out.append(memKB/1024);
15886        out.append(stackLike ? "MB." : "MB ");
15887        out.append(label, start, end);
15888    }
15889
15890    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15891            ProcessList.NATIVE_ADJ,
15892            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15893            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15894            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15895            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15896            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15897            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
15898    };
15899    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15900            "Native",
15901            "System", "Persistent", "Persistent Service", "Foreground",
15902            "Visible", "Perceptible",
15903            "Heavy Weight", "Backup",
15904            "A Services", "Home",
15905            "Previous", "B Services", "Cached"
15906    };
15907    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15908            "native",
15909            "sys", "pers", "persvc", "fore",
15910            "vis", "percept",
15911            "heavy", "backup",
15912            "servicea", "home",
15913            "prev", "serviceb", "cached"
15914    };
15915
15916    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15917            long realtime, boolean isCheckinRequest, boolean isCompact) {
15918        if (isCompact) {
15919            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15920        }
15921        if (isCheckinRequest || isCompact) {
15922            // short checkin version
15923            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15924        } else {
15925            pw.println("Applications Memory Usage (in Kilobytes):");
15926            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15927        }
15928    }
15929
15930    private static final int KSM_SHARED = 0;
15931    private static final int KSM_SHARING = 1;
15932    private static final int KSM_UNSHARED = 2;
15933    private static final int KSM_VOLATILE = 3;
15934
15935    private final long[] getKsmInfo() {
15936        long[] longOut = new long[4];
15937        final int[] SINGLE_LONG_FORMAT = new int[] {
15938            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15939        };
15940        long[] longTmp = new long[1];
15941        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15942                SINGLE_LONG_FORMAT, null, longTmp, null);
15943        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15944        longTmp[0] = 0;
15945        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15946                SINGLE_LONG_FORMAT, null, longTmp, null);
15947        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15948        longTmp[0] = 0;
15949        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15950                SINGLE_LONG_FORMAT, null, longTmp, null);
15951        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15952        longTmp[0] = 0;
15953        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15954                SINGLE_LONG_FORMAT, null, longTmp, null);
15955        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15956        return longOut;
15957    }
15958
15959    private static String stringifySize(long size, int order) {
15960        Locale locale = Locale.US;
15961        switch (order) {
15962            case 1:
15963                return String.format(locale, "%,13d", size);
15964            case 1024:
15965                return String.format(locale, "%,9dK", size / 1024);
15966            case 1024 * 1024:
15967                return String.format(locale, "%,5dM", size / 1024 / 1024);
15968            case 1024 * 1024 * 1024:
15969                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15970            default:
15971                throw new IllegalArgumentException("Invalid size order");
15972        }
15973    }
15974
15975    private static String stringifyKBSize(long size) {
15976        return stringifySize(size * 1024, 1024);
15977    }
15978
15979    // Update this version number in case you change the 'compact' format
15980    private static final int MEMINFO_COMPACT_VERSION = 1;
15981
15982    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15983            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15984        boolean dumpDetails = false;
15985        boolean dumpFullDetails = false;
15986        boolean dumpDalvik = false;
15987        boolean dumpSummaryOnly = false;
15988        boolean dumpUnreachable = false;
15989        boolean oomOnly = false;
15990        boolean isCompact = false;
15991        boolean localOnly = false;
15992        boolean packages = false;
15993        boolean isCheckinRequest = false;
15994        boolean dumpSwapPss = false;
15995
15996        int opti = 0;
15997        while (opti < args.length) {
15998            String opt = args[opti];
15999            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
16000                break;
16001            }
16002            opti++;
16003            if ("-a".equals(opt)) {
16004                dumpDetails = true;
16005                dumpFullDetails = true;
16006                dumpDalvik = true;
16007                dumpSwapPss = true;
16008            } else if ("-d".equals(opt)) {
16009                dumpDalvik = true;
16010            } else if ("-c".equals(opt)) {
16011                isCompact = true;
16012            } else if ("-s".equals(opt)) {
16013                dumpDetails = true;
16014                dumpSummaryOnly = true;
16015            } else if ("-S".equals(opt)) {
16016                dumpSwapPss = true;
16017            } else if ("--unreachable".equals(opt)) {
16018                dumpUnreachable = true;
16019            } else if ("--oom".equals(opt)) {
16020                oomOnly = true;
16021            } else if ("--local".equals(opt)) {
16022                localOnly = true;
16023            } else if ("--package".equals(opt)) {
16024                packages = true;
16025            } else if ("--checkin".equals(opt)) {
16026                isCheckinRequest = true;
16027
16028            } else if ("-h".equals(opt)) {
16029                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
16030                pw.println("  -a: include all available information for each process.");
16031                pw.println("  -d: include dalvik details.");
16032                pw.println("  -c: dump in a compact machine-parseable representation.");
16033                pw.println("  -s: dump only summary of application memory usage.");
16034                pw.println("  -S: dump also SwapPss.");
16035                pw.println("  --oom: only show processes organized by oom adj.");
16036                pw.println("  --local: only collect details locally, don't call process.");
16037                pw.println("  --package: interpret process arg as package, dumping all");
16038                pw.println("             processes that have loaded that package.");
16039                pw.println("  --checkin: dump data for a checkin");
16040                pw.println("If [process] is specified it can be the name or ");
16041                pw.println("pid of a specific process to dump.");
16042                return;
16043            } else {
16044                pw.println("Unknown argument: " + opt + "; use -h for help");
16045            }
16046        }
16047
16048        long uptime = SystemClock.uptimeMillis();
16049        long realtime = SystemClock.elapsedRealtime();
16050        final long[] tmpLong = new long[1];
16051
16052        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
16053        if (procs == null) {
16054            // No Java processes.  Maybe they want to print a native process.
16055            if (args != null && args.length > opti
16056                    && args[opti].charAt(0) != '-') {
16057                ArrayList<ProcessCpuTracker.Stats> nativeProcs
16058                        = new ArrayList<ProcessCpuTracker.Stats>();
16059                updateCpuStatsNow();
16060                int findPid = -1;
16061                try {
16062                    findPid = Integer.parseInt(args[opti]);
16063                } catch (NumberFormatException e) {
16064                }
16065                synchronized (mProcessCpuTracker) {
16066                    final int N = mProcessCpuTracker.countStats();
16067                    for (int i=0; i<N; i++) {
16068                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16069                        if (st.pid == findPid || (st.baseName != null
16070                                && st.baseName.equals(args[opti]))) {
16071                            nativeProcs.add(st);
16072                        }
16073                    }
16074                }
16075                if (nativeProcs.size() > 0) {
16076                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
16077                            isCompact);
16078                    Debug.MemoryInfo mi = null;
16079                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
16080                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
16081                        final int pid = r.pid;
16082                        if (!isCheckinRequest && dumpDetails) {
16083                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
16084                        }
16085                        if (mi == null) {
16086                            mi = new Debug.MemoryInfo();
16087                        }
16088                        if (dumpDetails || (!brief && !oomOnly)) {
16089                            Debug.getMemoryInfo(pid, mi);
16090                        } else {
16091                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16092                            mi.dalvikPrivateDirty = (int)tmpLong[0];
16093                        }
16094                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16095                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
16096                        if (isCheckinRequest) {
16097                            pw.println();
16098                        }
16099                    }
16100                    return;
16101                }
16102            }
16103            pw.println("No process found for: " + args[opti]);
16104            return;
16105        }
16106
16107        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
16108            dumpDetails = true;
16109        }
16110
16111        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
16112
16113        String[] innerArgs = new String[args.length-opti];
16114        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
16115
16116        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
16117        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
16118        long nativePss = 0;
16119        long nativeSwapPss = 0;
16120        long dalvikPss = 0;
16121        long dalvikSwapPss = 0;
16122        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16123                EmptyArray.LONG;
16124        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16125                EmptyArray.LONG;
16126        long otherPss = 0;
16127        long otherSwapPss = 0;
16128        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16129        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16130
16131        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16132        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16133        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
16134                new ArrayList[DUMP_MEM_OOM_LABEL.length];
16135
16136        long totalPss = 0;
16137        long totalSwapPss = 0;
16138        long cachedPss = 0;
16139        long cachedSwapPss = 0;
16140        boolean hasSwapPss = false;
16141
16142        Debug.MemoryInfo mi = null;
16143        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16144            final ProcessRecord r = procs.get(i);
16145            final IApplicationThread thread;
16146            final int pid;
16147            final int oomAdj;
16148            final boolean hasActivities;
16149            synchronized (this) {
16150                thread = r.thread;
16151                pid = r.pid;
16152                oomAdj = r.getSetAdjWithServices();
16153                hasActivities = r.activities.size() > 0;
16154            }
16155            if (thread != null) {
16156                if (!isCheckinRequest && dumpDetails) {
16157                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
16158                }
16159                if (mi == null) {
16160                    mi = new Debug.MemoryInfo();
16161                }
16162                if (dumpDetails || (!brief && !oomOnly)) {
16163                    Debug.getMemoryInfo(pid, mi);
16164                    hasSwapPss = mi.hasSwappedOutPss;
16165                } else {
16166                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16167                    mi.dalvikPrivateDirty = (int)tmpLong[0];
16168                }
16169                if (dumpDetails) {
16170                    if (localOnly) {
16171                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16172                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
16173                        if (isCheckinRequest) {
16174                            pw.println();
16175                        }
16176                    } else {
16177                        try {
16178                            pw.flush();
16179                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
16180                                    dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
16181                        } catch (RemoteException e) {
16182                            if (!isCheckinRequest) {
16183                                pw.println("Got RemoteException!");
16184                                pw.flush();
16185                            }
16186                        }
16187                    }
16188                }
16189
16190                final long myTotalPss = mi.getTotalPss();
16191                final long myTotalUss = mi.getTotalUss();
16192                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16193
16194                synchronized (this) {
16195                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
16196                        // Record this for posterity if the process has been stable.
16197                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
16198                    }
16199                }
16200
16201                if (!isCheckinRequest && mi != null) {
16202                    totalPss += myTotalPss;
16203                    totalSwapPss += myTotalSwapPss;
16204                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
16205                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
16206                            myTotalSwapPss, pid, hasActivities);
16207                    procMems.add(pssItem);
16208                    procMemsMap.put(pid, pssItem);
16209
16210                    nativePss += mi.nativePss;
16211                    nativeSwapPss += mi.nativeSwappedOutPss;
16212                    dalvikPss += mi.dalvikPss;
16213                    dalvikSwapPss += mi.dalvikSwappedOutPss;
16214                    for (int j=0; j<dalvikSubitemPss.length; j++) {
16215                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16216                        dalvikSubitemSwapPss[j] +=
16217                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16218                    }
16219                    otherPss += mi.otherPss;
16220                    otherSwapPss += mi.otherSwappedOutPss;
16221                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16222                        long mem = mi.getOtherPss(j);
16223                        miscPss[j] += mem;
16224                        otherPss -= mem;
16225                        mem = mi.getOtherSwappedOutPss(j);
16226                        miscSwapPss[j] += mem;
16227                        otherSwapPss -= mem;
16228                    }
16229
16230                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16231                        cachedPss += myTotalPss;
16232                        cachedSwapPss += myTotalSwapPss;
16233                    }
16234
16235                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
16236                        if (oomIndex == (oomPss.length - 1)
16237                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
16238                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
16239                            oomPss[oomIndex] += myTotalPss;
16240                            oomSwapPss[oomIndex] += myTotalSwapPss;
16241                            if (oomProcs[oomIndex] == null) {
16242                                oomProcs[oomIndex] = new ArrayList<MemItem>();
16243                            }
16244                            oomProcs[oomIndex].add(pssItem);
16245                            break;
16246                        }
16247                    }
16248                }
16249            }
16250        }
16251
16252        long nativeProcTotalPss = 0;
16253
16254        if (!isCheckinRequest && procs.size() > 1 && !packages) {
16255            // If we are showing aggregations, also look for native processes to
16256            // include so that our aggregations are more accurate.
16257            updateCpuStatsNow();
16258            mi = null;
16259            synchronized (mProcessCpuTracker) {
16260                final int N = mProcessCpuTracker.countStats();
16261                for (int i=0; i<N; i++) {
16262                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16263                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
16264                        if (mi == null) {
16265                            mi = new Debug.MemoryInfo();
16266                        }
16267                        if (!brief && !oomOnly) {
16268                            Debug.getMemoryInfo(st.pid, mi);
16269                        } else {
16270                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
16271                            mi.nativePrivateDirty = (int)tmpLong[0];
16272                        }
16273
16274                        final long myTotalPss = mi.getTotalPss();
16275                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16276                        totalPss += myTotalPss;
16277                        nativeProcTotalPss += myTotalPss;
16278
16279                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
16280                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
16281                        procMems.add(pssItem);
16282
16283                        nativePss += mi.nativePss;
16284                        nativeSwapPss += mi.nativeSwappedOutPss;
16285                        dalvikPss += mi.dalvikPss;
16286                        dalvikSwapPss += mi.dalvikSwappedOutPss;
16287                        for (int j=0; j<dalvikSubitemPss.length; j++) {
16288                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16289                            dalvikSubitemSwapPss[j] +=
16290                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16291                        }
16292                        otherPss += mi.otherPss;
16293                        otherSwapPss += mi.otherSwappedOutPss;
16294                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16295                            long mem = mi.getOtherPss(j);
16296                            miscPss[j] += mem;
16297                            otherPss -= mem;
16298                            mem = mi.getOtherSwappedOutPss(j);
16299                            miscSwapPss[j] += mem;
16300                            otherSwapPss -= mem;
16301                        }
16302                        oomPss[0] += myTotalPss;
16303                        oomSwapPss[0] += myTotalSwapPss;
16304                        if (oomProcs[0] == null) {
16305                            oomProcs[0] = new ArrayList<MemItem>();
16306                        }
16307                        oomProcs[0].add(pssItem);
16308                    }
16309                }
16310            }
16311
16312            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
16313
16314            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
16315            final MemItem dalvikItem =
16316                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
16317            if (dalvikSubitemPss.length > 0) {
16318                dalvikItem.subitems = new ArrayList<MemItem>();
16319                for (int j=0; j<dalvikSubitemPss.length; j++) {
16320                    final String name = Debug.MemoryInfo.getOtherLabel(
16321                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
16322                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
16323                                    dalvikSubitemSwapPss[j], j));
16324                }
16325            }
16326            catMems.add(dalvikItem);
16327            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
16328            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16329                String label = Debug.MemoryInfo.getOtherLabel(j);
16330                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
16331            }
16332
16333            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
16334            for (int j=0; j<oomPss.length; j++) {
16335                if (oomPss[j] != 0) {
16336                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
16337                            : DUMP_MEM_OOM_LABEL[j];
16338                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
16339                            DUMP_MEM_OOM_ADJ[j]);
16340                    item.subitems = oomProcs[j];
16341                    oomMems.add(item);
16342                }
16343            }
16344
16345            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
16346            if (!brief && !oomOnly && !isCompact) {
16347                pw.println();
16348                pw.println("Total PSS by process:");
16349                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
16350                pw.println();
16351            }
16352            if (!isCompact) {
16353                pw.println("Total PSS by OOM adjustment:");
16354            }
16355            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
16356            if (!brief && !oomOnly) {
16357                PrintWriter out = categoryPw != null ? categoryPw : pw;
16358                if (!isCompact) {
16359                    out.println();
16360                    out.println("Total PSS by category:");
16361                }
16362                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
16363            }
16364            if (!isCompact) {
16365                pw.println();
16366            }
16367            MemInfoReader memInfo = new MemInfoReader();
16368            memInfo.readMemInfo();
16369            if (nativeProcTotalPss > 0) {
16370                synchronized (this) {
16371                    final long cachedKb = memInfo.getCachedSizeKb();
16372                    final long freeKb = memInfo.getFreeSizeKb();
16373                    final long zramKb = memInfo.getZramTotalSizeKb();
16374                    final long kernelKb = memInfo.getKernelUsedSizeKb();
16375                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
16376                            kernelKb*1024, nativeProcTotalPss*1024);
16377                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
16378                            nativeProcTotalPss);
16379                }
16380            }
16381            if (!brief) {
16382                if (!isCompact) {
16383                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
16384                    pw.print(" (status ");
16385                    switch (mLastMemoryLevel) {
16386                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
16387                            pw.println("normal)");
16388                            break;
16389                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
16390                            pw.println("moderate)");
16391                            break;
16392                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
16393                            pw.println("low)");
16394                            break;
16395                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16396                            pw.println("critical)");
16397                            break;
16398                        default:
16399                            pw.print(mLastMemoryLevel);
16400                            pw.println(")");
16401                            break;
16402                    }
16403                    pw.print(" Free RAM: ");
16404                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16405                            + memInfo.getFreeSizeKb()));
16406                    pw.print(" (");
16407                    pw.print(stringifyKBSize(cachedPss));
16408                    pw.print(" cached pss + ");
16409                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
16410                    pw.print(" cached kernel + ");
16411                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
16412                    pw.println(" free)");
16413                } else {
16414                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
16415                    pw.print(cachedPss + memInfo.getCachedSizeKb()
16416                            + memInfo.getFreeSizeKb()); pw.print(",");
16417                    pw.println(totalPss - cachedPss);
16418                }
16419            }
16420            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
16421                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16422                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
16423            if (!isCompact) {
16424                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
16425                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
16426                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
16427                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
16428                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
16429            } else {
16430                pw.print("lostram,"); pw.println(lostRAM);
16431            }
16432            if (!brief) {
16433                if (memInfo.getZramTotalSizeKb() != 0) {
16434                    if (!isCompact) {
16435                        pw.print("     ZRAM: ");
16436                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
16437                                pw.print(" physical used for ");
16438                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
16439                                        - memInfo.getSwapFreeSizeKb()));
16440                                pw.print(" in swap (");
16441                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
16442                                pw.println(" total swap)");
16443                    } else {
16444                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
16445                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
16446                                pw.println(memInfo.getSwapFreeSizeKb());
16447                    }
16448                }
16449                final long[] ksm = getKsmInfo();
16450                if (!isCompact) {
16451                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16452                            || ksm[KSM_VOLATILE] != 0) {
16453                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
16454                                pw.print(" saved from shared ");
16455                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
16456                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
16457                                pw.print(" unshared; ");
16458                                pw.print(stringifyKBSize(
16459                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
16460                    }
16461                    pw.print("   Tuning: ");
16462                    pw.print(ActivityManager.staticGetMemoryClass());
16463                    pw.print(" (large ");
16464                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16465                    pw.print("), oom ");
16466                    pw.print(stringifySize(
16467                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
16468                    pw.print(", restore limit ");
16469                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
16470                    if (ActivityManager.isLowRamDeviceStatic()) {
16471                        pw.print(" (low-ram)");
16472                    }
16473                    if (ActivityManager.isHighEndGfx()) {
16474                        pw.print(" (high-end-gfx)");
16475                    }
16476                    pw.println();
16477                } else {
16478                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16479                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16480                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16481                    pw.print("tuning,");
16482                    pw.print(ActivityManager.staticGetMemoryClass());
16483                    pw.print(',');
16484                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16485                    pw.print(',');
16486                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16487                    if (ActivityManager.isLowRamDeviceStatic()) {
16488                        pw.print(",low-ram");
16489                    }
16490                    if (ActivityManager.isHighEndGfx()) {
16491                        pw.print(",high-end-gfx");
16492                    }
16493                    pw.println();
16494                }
16495            }
16496        }
16497    }
16498
16499    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16500            long memtrack, String name) {
16501        sb.append("  ");
16502        sb.append(ProcessList.makeOomAdjString(oomAdj));
16503        sb.append(' ');
16504        sb.append(ProcessList.makeProcStateString(procState));
16505        sb.append(' ');
16506        ProcessList.appendRamKb(sb, pss);
16507        sb.append(": ");
16508        sb.append(name);
16509        if (memtrack > 0) {
16510            sb.append(" (");
16511            sb.append(stringifyKBSize(memtrack));
16512            sb.append(" memtrack)");
16513        }
16514    }
16515
16516    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16517        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16518        sb.append(" (pid ");
16519        sb.append(mi.pid);
16520        sb.append(") ");
16521        sb.append(mi.adjType);
16522        sb.append('\n');
16523        if (mi.adjReason != null) {
16524            sb.append("                      ");
16525            sb.append(mi.adjReason);
16526            sb.append('\n');
16527        }
16528    }
16529
16530    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16531        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16532        for (int i=0, N=memInfos.size(); i<N; i++) {
16533            ProcessMemInfo mi = memInfos.get(i);
16534            infoMap.put(mi.pid, mi);
16535        }
16536        updateCpuStatsNow();
16537        long[] memtrackTmp = new long[1];
16538        final List<ProcessCpuTracker.Stats> stats;
16539        // Get a list of Stats that have vsize > 0
16540        synchronized (mProcessCpuTracker) {
16541            stats = mProcessCpuTracker.getStats((st) -> {
16542                return st.vsize > 0;
16543            });
16544        }
16545        final int statsCount = stats.size();
16546        for (int i = 0; i < statsCount; i++) {
16547            ProcessCpuTracker.Stats st = stats.get(i);
16548            long pss = Debug.getPss(st.pid, null, memtrackTmp);
16549            if (pss > 0) {
16550                if (infoMap.indexOfKey(st.pid) < 0) {
16551                    ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16552                            ProcessList.NATIVE_ADJ, -1, "native", null);
16553                    mi.pss = pss;
16554                    mi.memtrack = memtrackTmp[0];
16555                    memInfos.add(mi);
16556                }
16557            }
16558        }
16559
16560        long totalPss = 0;
16561        long totalMemtrack = 0;
16562        for (int i=0, N=memInfos.size(); i<N; i++) {
16563            ProcessMemInfo mi = memInfos.get(i);
16564            if (mi.pss == 0) {
16565                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16566                mi.memtrack = memtrackTmp[0];
16567            }
16568            totalPss += mi.pss;
16569            totalMemtrack += mi.memtrack;
16570        }
16571        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16572            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16573                if (lhs.oomAdj != rhs.oomAdj) {
16574                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16575                }
16576                if (lhs.pss != rhs.pss) {
16577                    return lhs.pss < rhs.pss ? 1 : -1;
16578                }
16579                return 0;
16580            }
16581        });
16582
16583        StringBuilder tag = new StringBuilder(128);
16584        StringBuilder stack = new StringBuilder(128);
16585        tag.append("Low on memory -- ");
16586        appendMemBucket(tag, totalPss, "total", false);
16587        appendMemBucket(stack, totalPss, "total", true);
16588
16589        StringBuilder fullNativeBuilder = new StringBuilder(1024);
16590        StringBuilder shortNativeBuilder = new StringBuilder(1024);
16591        StringBuilder fullJavaBuilder = new StringBuilder(1024);
16592
16593        boolean firstLine = true;
16594        int lastOomAdj = Integer.MIN_VALUE;
16595        long extraNativeRam = 0;
16596        long extraNativeMemtrack = 0;
16597        long cachedPss = 0;
16598        for (int i=0, N=memInfos.size(); i<N; i++) {
16599            ProcessMemInfo mi = memInfos.get(i);
16600
16601            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16602                cachedPss += mi.pss;
16603            }
16604
16605            if (mi.oomAdj != ProcessList.NATIVE_ADJ
16606                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
16607                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
16608                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16609                if (lastOomAdj != mi.oomAdj) {
16610                    lastOomAdj = mi.oomAdj;
16611                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16612                        tag.append(" / ");
16613                    }
16614                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16615                        if (firstLine) {
16616                            stack.append(":");
16617                            firstLine = false;
16618                        }
16619                        stack.append("\n\t at ");
16620                    } else {
16621                        stack.append("$");
16622                    }
16623                } else {
16624                    tag.append(" ");
16625                    stack.append("$");
16626                }
16627                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16628                    appendMemBucket(tag, mi.pss, mi.name, false);
16629                }
16630                appendMemBucket(stack, mi.pss, mi.name, true);
16631                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16632                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16633                    stack.append("(");
16634                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16635                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16636                            stack.append(DUMP_MEM_OOM_LABEL[k]);
16637                            stack.append(":");
16638                            stack.append(DUMP_MEM_OOM_ADJ[k]);
16639                        }
16640                    }
16641                    stack.append(")");
16642                }
16643            }
16644
16645            appendMemInfo(fullNativeBuilder, mi);
16646            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16647                // The short form only has native processes that are >= 512K.
16648                if (mi.pss >= 512) {
16649                    appendMemInfo(shortNativeBuilder, mi);
16650                } else {
16651                    extraNativeRam += mi.pss;
16652                    extraNativeMemtrack += mi.memtrack;
16653                }
16654            } else {
16655                // Short form has all other details, but if we have collected RAM
16656                // from smaller native processes let's dump a summary of that.
16657                if (extraNativeRam > 0) {
16658                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16659                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16660                    shortNativeBuilder.append('\n');
16661                    extraNativeRam = 0;
16662                }
16663                appendMemInfo(fullJavaBuilder, mi);
16664            }
16665        }
16666
16667        fullJavaBuilder.append("           ");
16668        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16669        fullJavaBuilder.append(": TOTAL");
16670        if (totalMemtrack > 0) {
16671            fullJavaBuilder.append(" (");
16672            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16673            fullJavaBuilder.append(" memtrack)");
16674        } else {
16675        }
16676        fullJavaBuilder.append("\n");
16677
16678        MemInfoReader memInfo = new MemInfoReader();
16679        memInfo.readMemInfo();
16680        final long[] infos = memInfo.getRawInfo();
16681
16682        StringBuilder memInfoBuilder = new StringBuilder(1024);
16683        Debug.getMemInfo(infos);
16684        memInfoBuilder.append("  MemInfo: ");
16685        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16686        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16687        memInfoBuilder.append(stringifyKBSize(
16688                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16689        memInfoBuilder.append(stringifyKBSize(
16690                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16691        memInfoBuilder.append(stringifyKBSize(
16692                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16693        memInfoBuilder.append("           ");
16694        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16695        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16696        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16697        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16698        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16699            memInfoBuilder.append("  ZRAM: ");
16700            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16701            memInfoBuilder.append(" RAM, ");
16702            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16703            memInfoBuilder.append(" swap total, ");
16704            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16705            memInfoBuilder.append(" swap free\n");
16706        }
16707        final long[] ksm = getKsmInfo();
16708        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16709                || ksm[KSM_VOLATILE] != 0) {
16710            memInfoBuilder.append("  KSM: ");
16711            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16712            memInfoBuilder.append(" saved from shared ");
16713            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16714            memInfoBuilder.append("\n       ");
16715            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16716            memInfoBuilder.append(" unshared; ");
16717            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16718            memInfoBuilder.append(" volatile\n");
16719        }
16720        memInfoBuilder.append("  Free RAM: ");
16721        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16722                + memInfo.getFreeSizeKb()));
16723        memInfoBuilder.append("\n");
16724        memInfoBuilder.append("  Used RAM: ");
16725        memInfoBuilder.append(stringifyKBSize(
16726                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16727        memInfoBuilder.append("\n");
16728        memInfoBuilder.append("  Lost RAM: ");
16729        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16730                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16731                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16732        memInfoBuilder.append("\n");
16733        Slog.i(TAG, "Low on memory:");
16734        Slog.i(TAG, shortNativeBuilder.toString());
16735        Slog.i(TAG, fullJavaBuilder.toString());
16736        Slog.i(TAG, memInfoBuilder.toString());
16737
16738        StringBuilder dropBuilder = new StringBuilder(1024);
16739        /*
16740        StringWriter oomSw = new StringWriter();
16741        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16742        StringWriter catSw = new StringWriter();
16743        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16744        String[] emptyArgs = new String[] { };
16745        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16746        oomPw.flush();
16747        String oomString = oomSw.toString();
16748        */
16749        dropBuilder.append("Low on memory:");
16750        dropBuilder.append(stack);
16751        dropBuilder.append('\n');
16752        dropBuilder.append(fullNativeBuilder);
16753        dropBuilder.append(fullJavaBuilder);
16754        dropBuilder.append('\n');
16755        dropBuilder.append(memInfoBuilder);
16756        dropBuilder.append('\n');
16757        /*
16758        dropBuilder.append(oomString);
16759        dropBuilder.append('\n');
16760        */
16761        StringWriter catSw = new StringWriter();
16762        synchronized (ActivityManagerService.this) {
16763            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16764            String[] emptyArgs = new String[] { };
16765            catPw.println();
16766            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16767            catPw.println();
16768            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
16769                    false, null).dumpLocked();
16770            catPw.println();
16771            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16772            catPw.flush();
16773        }
16774        dropBuilder.append(catSw.toString());
16775        addErrorToDropBox("lowmem", null, "system_server", null,
16776                null, tag.toString(), dropBuilder.toString(), null, null);
16777        //Slog.i(TAG, "Sent to dropbox:");
16778        //Slog.i(TAG, dropBuilder.toString());
16779        synchronized (ActivityManagerService.this) {
16780            long now = SystemClock.uptimeMillis();
16781            if (mLastMemUsageReportTime < now) {
16782                mLastMemUsageReportTime = now;
16783            }
16784        }
16785    }
16786
16787    /**
16788     * Searches array of arguments for the specified string
16789     * @param args array of argument strings
16790     * @param value value to search for
16791     * @return true if the value is contained in the array
16792     */
16793    private static boolean scanArgs(String[] args, String value) {
16794        if (args != null) {
16795            for (String arg : args) {
16796                if (value.equals(arg)) {
16797                    return true;
16798                }
16799            }
16800        }
16801        return false;
16802    }
16803
16804    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16805            ContentProviderRecord cpr, boolean always) {
16806        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16807
16808        if (!inLaunching || always) {
16809            synchronized (cpr) {
16810                cpr.launchingApp = null;
16811                cpr.notifyAll();
16812            }
16813            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16814            String names[] = cpr.info.authority.split(";");
16815            for (int j = 0; j < names.length; j++) {
16816                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16817            }
16818        }
16819
16820        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16821            ContentProviderConnection conn = cpr.connections.get(i);
16822            if (conn.waiting) {
16823                // If this connection is waiting for the provider, then we don't
16824                // need to mess with its process unless we are always removing
16825                // or for some reason the provider is not currently launching.
16826                if (inLaunching && !always) {
16827                    continue;
16828                }
16829            }
16830            ProcessRecord capp = conn.client;
16831            conn.dead = true;
16832            if (conn.stableCount > 0) {
16833                if (!capp.persistent && capp.thread != null
16834                        && capp.pid != 0
16835                        && capp.pid != MY_PID) {
16836                    capp.kill("depends on provider "
16837                            + cpr.name.flattenToShortString()
16838                            + " in dying proc " + (proc != null ? proc.processName : "??")
16839                            + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
16840                }
16841            } else if (capp.thread != null && conn.provider.provider != null) {
16842                try {
16843                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16844                } catch (RemoteException e) {
16845                }
16846                // In the protocol here, we don't expect the client to correctly
16847                // clean up this connection, we'll just remove it.
16848                cpr.connections.remove(i);
16849                if (conn.client.conProviders.remove(conn)) {
16850                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16851                }
16852            }
16853        }
16854
16855        if (inLaunching && always) {
16856            mLaunchingProviders.remove(cpr);
16857        }
16858        return inLaunching;
16859    }
16860
16861    /**
16862     * Main code for cleaning up a process when it has gone away.  This is
16863     * called both as a result of the process dying, or directly when stopping
16864     * a process when running in single process mode.
16865     *
16866     * @return Returns true if the given process has been restarted, so the
16867     * app that was passed in must remain on the process lists.
16868     */
16869    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16870            boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
16871        Slog.d(TAG, "cleanUpApplicationRecord -- " + app.pid);
16872        if (index >= 0) {
16873            removeLruProcessLocked(app);
16874            ProcessList.remove(app.pid);
16875        }
16876
16877        mProcessesToGc.remove(app);
16878        mPendingPssProcesses.remove(app);
16879
16880        // Dismiss any open dialogs.
16881        if (app.crashDialog != null && !app.forceCrashReport) {
16882            app.crashDialog.dismiss();
16883            app.crashDialog = null;
16884        }
16885        if (app.anrDialog != null) {
16886            app.anrDialog.dismiss();
16887            app.anrDialog = null;
16888        }
16889        if (app.waitDialog != null) {
16890            app.waitDialog.dismiss();
16891            app.waitDialog = null;
16892        }
16893
16894        app.crashing = false;
16895        app.notResponding = false;
16896
16897        app.resetPackageList(mProcessStats);
16898        app.unlinkDeathRecipient();
16899        app.makeInactive(mProcessStats);
16900        app.waitingToKill = null;
16901        app.forcingToForeground = null;
16902        updateProcessForegroundLocked(app, false, false);
16903        app.foregroundActivities = false;
16904        app.hasShownUi = false;
16905        app.treatLikeActivity = false;
16906        app.hasAboveClient = false;
16907        app.hasClientActivities = false;
16908
16909        mServices.killServicesLocked(app, allowRestart);
16910
16911        boolean restart = false;
16912
16913        // Remove published content providers.
16914        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16915            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16916            final boolean always = app.bad || !allowRestart;
16917            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16918            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16919                // We left the provider in the launching list, need to
16920                // restart it.
16921                restart = true;
16922            }
16923
16924            cpr.provider = null;
16925            cpr.proc = null;
16926        }
16927        app.pubProviders.clear();
16928
16929        // Take care of any launching providers waiting for this process.
16930        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16931            restart = true;
16932        }
16933
16934        // Unregister from connected content providers.
16935        if (!app.conProviders.isEmpty()) {
16936            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16937                ContentProviderConnection conn = app.conProviders.get(i);
16938                conn.provider.connections.remove(conn);
16939                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16940                        conn.provider.name);
16941            }
16942            app.conProviders.clear();
16943        }
16944
16945        // At this point there may be remaining entries in mLaunchingProviders
16946        // where we were the only one waiting, so they are no longer of use.
16947        // Look for these and clean up if found.
16948        // XXX Commented out for now.  Trying to figure out a way to reproduce
16949        // the actual situation to identify what is actually going on.
16950        if (false) {
16951            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16952                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16953                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16954                    synchronized (cpr) {
16955                        cpr.launchingApp = null;
16956                        cpr.notifyAll();
16957                    }
16958                }
16959            }
16960        }
16961
16962        skipCurrentReceiverLocked(app);
16963
16964        // Unregister any receivers.
16965        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16966            removeReceiverLocked(app.receivers.valueAt(i));
16967        }
16968        app.receivers.clear();
16969
16970        // If the app is undergoing backup, tell the backup manager about it
16971        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16972            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16973                    + mBackupTarget.appInfo + " died during backup");
16974            try {
16975                IBackupManager bm = IBackupManager.Stub.asInterface(
16976                        ServiceManager.getService(Context.BACKUP_SERVICE));
16977                bm.agentDisconnected(app.info.packageName);
16978            } catch (RemoteException e) {
16979                // can't happen; backup manager is local
16980            }
16981        }
16982
16983        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16984            ProcessChangeItem item = mPendingProcessChanges.get(i);
16985            if (item.pid == app.pid) {
16986                mPendingProcessChanges.remove(i);
16987                mAvailProcessChanges.add(item);
16988            }
16989        }
16990        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16991                null).sendToTarget();
16992
16993        // If the caller is restarting this app, then leave it in its
16994        // current lists and let the caller take care of it.
16995        if (restarting) {
16996            return false;
16997        }
16998
16999        if (!app.persistent || app.isolated) {
17000            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
17001                    "Removing non-persistent process during cleanup: " + app);
17002            if (!replacingPid) {
17003                removeProcessNameLocked(app.processName, app.uid);
17004            }
17005            if (mHeavyWeightProcess == app) {
17006                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
17007                        mHeavyWeightProcess.userId, 0));
17008                mHeavyWeightProcess = null;
17009            }
17010        } else if (!app.removed) {
17011            // This app is persistent, so we need to keep its record around.
17012            // If it is not already on the pending app list, add it there
17013            // and start a new process for it.
17014            if (mPersistentStartingProcesses.indexOf(app) < 0) {
17015                mPersistentStartingProcesses.add(app);
17016                restart = true;
17017            }
17018        }
17019        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
17020                TAG_CLEANUP, "Clean-up removing on hold: " + app);
17021        mProcessesOnHold.remove(app);
17022
17023        if (app == mHomeProcess) {
17024            mHomeProcess = null;
17025        }
17026        if (app == mPreviousProcess) {
17027            mPreviousProcess = null;
17028        }
17029
17030        if (restart && !app.isolated) {
17031            // We have components that still need to be running in the
17032            // process, so re-launch it.
17033            if (index < 0) {
17034                ProcessList.remove(app.pid);
17035            }
17036            addProcessNameLocked(app);
17037            startProcessLocked(app, "restart", app.processName);
17038            return true;
17039        } else if (app.pid > 0 && app.pid != MY_PID) {
17040            // Goodbye!
17041            boolean removed;
17042            synchronized (mPidsSelfLocked) {
17043                mPidsSelfLocked.remove(app.pid);
17044                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
17045            }
17046            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
17047            if (app.isolated) {
17048                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
17049            }
17050            app.setPid(0);
17051        }
17052        return false;
17053    }
17054
17055    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
17056        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17057            ContentProviderRecord cpr = mLaunchingProviders.get(i);
17058            if (cpr.launchingApp == app) {
17059                return true;
17060            }
17061        }
17062        return false;
17063    }
17064
17065    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
17066        // Look through the content providers we are waiting to have launched,
17067        // and if any run in this process then either schedule a restart of
17068        // the process or kill the client waiting for it if this process has
17069        // gone bad.
17070        boolean restart = false;
17071        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17072            ContentProviderRecord cpr = mLaunchingProviders.get(i);
17073            if (cpr.launchingApp == app) {
17074                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
17075                    restart = true;
17076                } else {
17077                    removeDyingProviderLocked(app, cpr, true);
17078                }
17079            }
17080        }
17081        return restart;
17082    }
17083
17084    // =========================================================
17085    // SERVICES
17086    // =========================================================
17087
17088    @Override
17089    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
17090            int flags) {
17091        enforceNotIsolatedCaller("getServices");
17092        synchronized (this) {
17093            return mServices.getRunningServiceInfoLocked(maxNum, flags);
17094        }
17095    }
17096
17097    @Override
17098    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
17099        enforceNotIsolatedCaller("getRunningServiceControlPanel");
17100        synchronized (this) {
17101            return mServices.getRunningServiceControlPanelLocked(name);
17102        }
17103    }
17104
17105    @Override
17106    public ComponentName startService(IApplicationThread caller, Intent service,
17107            String resolvedType, String callingPackage, int userId)
17108            throws TransactionTooLargeException {
17109        enforceNotIsolatedCaller("startService");
17110        // Refuse possible leaked file descriptors
17111        if (service != null && service.hasFileDescriptors() == true) {
17112            throw new IllegalArgumentException("File descriptors passed in Intent");
17113        }
17114
17115        if (callingPackage == null) {
17116            throw new IllegalArgumentException("callingPackage cannot be null");
17117        }
17118
17119        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17120                "startService: " + service + " type=" + resolvedType);
17121        synchronized(this) {
17122            final int callingPid = Binder.getCallingPid();
17123            final int callingUid = Binder.getCallingUid();
17124            final long origId = Binder.clearCallingIdentity();
17125            ComponentName res = mServices.startServiceLocked(caller, service,
17126                    resolvedType, callingPid, callingUid, callingPackage, userId);
17127            Binder.restoreCallingIdentity(origId);
17128            return res;
17129        }
17130    }
17131
17132    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
17133            String callingPackage, int userId)
17134            throws TransactionTooLargeException {
17135        synchronized(this) {
17136            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17137                    "startServiceInPackage: " + service + " type=" + resolvedType);
17138            final long origId = Binder.clearCallingIdentity();
17139            ComponentName res = mServices.startServiceLocked(null, service,
17140                    resolvedType, -1, uid, callingPackage, userId);
17141            Binder.restoreCallingIdentity(origId);
17142            return res;
17143        }
17144    }
17145
17146    @Override
17147    public int stopService(IApplicationThread caller, Intent service,
17148            String resolvedType, int userId) {
17149        enforceNotIsolatedCaller("stopService");
17150        // Refuse possible leaked file descriptors
17151        if (service != null && service.hasFileDescriptors() == true) {
17152            throw new IllegalArgumentException("File descriptors passed in Intent");
17153        }
17154
17155        synchronized(this) {
17156            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
17157        }
17158    }
17159
17160    @Override
17161    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
17162        enforceNotIsolatedCaller("peekService");
17163        // Refuse possible leaked file descriptors
17164        if (service != null && service.hasFileDescriptors() == true) {
17165            throw new IllegalArgumentException("File descriptors passed in Intent");
17166        }
17167
17168        if (callingPackage == null) {
17169            throw new IllegalArgumentException("callingPackage cannot be null");
17170        }
17171
17172        synchronized(this) {
17173            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
17174        }
17175    }
17176
17177    @Override
17178    public boolean stopServiceToken(ComponentName className, IBinder token,
17179            int startId) {
17180        synchronized(this) {
17181            return mServices.stopServiceTokenLocked(className, token, startId);
17182        }
17183    }
17184
17185    @Override
17186    public void setServiceForeground(ComponentName className, IBinder token,
17187            int id, Notification notification, int flags) {
17188        synchronized(this) {
17189            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
17190        }
17191    }
17192
17193    @Override
17194    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
17195            boolean requireFull, String name, String callerPackage) {
17196        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
17197                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
17198    }
17199
17200    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
17201            String className, int flags) {
17202        boolean result = false;
17203        // For apps that don't have pre-defined UIDs, check for permission
17204        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
17205            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17206                if (ActivityManager.checkUidPermission(
17207                        INTERACT_ACROSS_USERS,
17208                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
17209                    ComponentName comp = new ComponentName(aInfo.packageName, className);
17210                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
17211                            + " requests FLAG_SINGLE_USER, but app does not hold "
17212                            + INTERACT_ACROSS_USERS;
17213                    Slog.w(TAG, msg);
17214                    throw new SecurityException(msg);
17215                }
17216                // Permission passed
17217                result = true;
17218            }
17219        } else if ("system".equals(componentProcessName)) {
17220            result = true;
17221        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17222            // Phone app and persistent apps are allowed to export singleuser providers.
17223            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
17224                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
17225        }
17226        if (DEBUG_MU) Slog.v(TAG_MU,
17227                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
17228                + Integer.toHexString(flags) + ") = " + result);
17229        return result;
17230    }
17231
17232    /**
17233     * Checks to see if the caller is in the same app as the singleton
17234     * component, or the component is in a special app. It allows special apps
17235     * to export singleton components but prevents exporting singleton
17236     * components for regular apps.
17237     */
17238    boolean isValidSingletonCall(int callingUid, int componentUid) {
17239        int componentAppId = UserHandle.getAppId(componentUid);
17240        return UserHandle.isSameApp(callingUid, componentUid)
17241                || componentAppId == Process.SYSTEM_UID
17242                || componentAppId == Process.PHONE_UID
17243                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
17244                        == PackageManager.PERMISSION_GRANTED;
17245    }
17246
17247    public int bindService(IApplicationThread caller, IBinder token, Intent service,
17248            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
17249            int userId) throws TransactionTooLargeException {
17250        enforceNotIsolatedCaller("bindService");
17251
17252        // Refuse possible leaked file descriptors
17253        if (service != null && service.hasFileDescriptors() == true) {
17254            throw new IllegalArgumentException("File descriptors passed in Intent");
17255        }
17256
17257        if (callingPackage == null) {
17258            throw new IllegalArgumentException("callingPackage cannot be null");
17259        }
17260
17261        synchronized(this) {
17262            return mServices.bindServiceLocked(caller, token, service,
17263                    resolvedType, connection, flags, callingPackage, userId);
17264        }
17265    }
17266
17267    public boolean unbindService(IServiceConnection connection) {
17268        synchronized (this) {
17269            return mServices.unbindServiceLocked(connection);
17270        }
17271    }
17272
17273    public void publishService(IBinder token, Intent intent, IBinder service) {
17274        // Refuse possible leaked file descriptors
17275        if (intent != null && intent.hasFileDescriptors() == true) {
17276            throw new IllegalArgumentException("File descriptors passed in Intent");
17277        }
17278
17279        synchronized(this) {
17280            if (!(token instanceof ServiceRecord)) {
17281                throw new IllegalArgumentException("Invalid service token");
17282            }
17283            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
17284        }
17285    }
17286
17287    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
17288        // Refuse possible leaked file descriptors
17289        if (intent != null && intent.hasFileDescriptors() == true) {
17290            throw new IllegalArgumentException("File descriptors passed in Intent");
17291        }
17292
17293        synchronized(this) {
17294            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
17295        }
17296    }
17297
17298    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
17299        synchronized(this) {
17300            if (!(token instanceof ServiceRecord)) {
17301                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
17302                throw new IllegalArgumentException("Invalid service token");
17303            }
17304            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
17305        }
17306    }
17307
17308    // =========================================================
17309    // BACKUP AND RESTORE
17310    // =========================================================
17311
17312    // Cause the target app to be launched if necessary and its backup agent
17313    // instantiated.  The backup agent will invoke backupAgentCreated() on the
17314    // activity manager to announce its creation.
17315    public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
17316        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
17317        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
17318
17319        IPackageManager pm = AppGlobals.getPackageManager();
17320        ApplicationInfo app = null;
17321        try {
17322            app = pm.getApplicationInfo(packageName, 0, userId);
17323        } catch (RemoteException e) {
17324            // can't happen; package manager is process-local
17325        }
17326        if (app == null) {
17327            Slog.w(TAG, "Unable to bind backup agent for " + packageName);
17328            return false;
17329        }
17330
17331        synchronized(this) {
17332            // !!! TODO: currently no check here that we're already bound
17333            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
17334            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17335            synchronized (stats) {
17336                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
17337            }
17338
17339            // Backup agent is now in use, its package can't be stopped.
17340            try {
17341                AppGlobals.getPackageManager().setPackageStoppedState(
17342                        app.packageName, false, UserHandle.getUserId(app.uid));
17343            } catch (RemoteException e) {
17344            } catch (IllegalArgumentException e) {
17345                Slog.w(TAG, "Failed trying to unstop package "
17346                        + app.packageName + ": " + e);
17347            }
17348
17349            BackupRecord r = new BackupRecord(ss, app, backupMode);
17350            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
17351                    ? new ComponentName(app.packageName, app.backupAgentName)
17352                    : new ComponentName("android", "FullBackupAgent");
17353            // startProcessLocked() returns existing proc's record if it's already running
17354            ProcessRecord proc = startProcessLocked(app.processName, app,
17355                    false, 0, "backup", hostingName, false, false, false);
17356            if (proc == null) {
17357                Slog.e(TAG, "Unable to start backup agent process " + r);
17358                return false;
17359            }
17360
17361            // If the app is a regular app (uid >= 10000) and not the system server or phone
17362            // process, etc, then mark it as being in full backup so that certain calls to the
17363            // process can be blocked. This is not reset to false anywhere because we kill the
17364            // process after the full backup is done and the ProcessRecord will vaporize anyway.
17365            if (UserHandle.isApp(app.uid) && backupMode == IApplicationThread.BACKUP_MODE_FULL) {
17366                proc.inFullBackup = true;
17367            }
17368            r.app = proc;
17369            mBackupTarget = r;
17370            mBackupAppName = app.packageName;
17371
17372            // Try not to kill the process during backup
17373            updateOomAdjLocked(proc);
17374
17375            // If the process is already attached, schedule the creation of the backup agent now.
17376            // If it is not yet live, this will be done when it attaches to the framework.
17377            if (proc.thread != null) {
17378                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
17379                try {
17380                    proc.thread.scheduleCreateBackupAgent(app,
17381                            compatibilityInfoForPackageLocked(app), backupMode);
17382                } catch (RemoteException e) {
17383                    // Will time out on the backup manager side
17384                }
17385            } else {
17386                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
17387            }
17388            // Invariants: at this point, the target app process exists and the application
17389            // is either already running or in the process of coming up.  mBackupTarget and
17390            // mBackupAppName describe the app, so that when it binds back to the AM we
17391            // know that it's scheduled for a backup-agent operation.
17392        }
17393
17394        return true;
17395    }
17396
17397    @Override
17398    public void clearPendingBackup() {
17399        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
17400        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
17401
17402        synchronized (this) {
17403            mBackupTarget = null;
17404            mBackupAppName = null;
17405        }
17406    }
17407
17408    // A backup agent has just come up
17409    public void backupAgentCreated(String agentPackageName, IBinder agent) {
17410        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
17411                + " = " + agent);
17412
17413        synchronized(this) {
17414            if (!agentPackageName.equals(mBackupAppName)) {
17415                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
17416                return;
17417            }
17418        }
17419
17420        long oldIdent = Binder.clearCallingIdentity();
17421        try {
17422            IBackupManager bm = IBackupManager.Stub.asInterface(
17423                    ServiceManager.getService(Context.BACKUP_SERVICE));
17424            bm.agentConnected(agentPackageName, agent);
17425        } catch (RemoteException e) {
17426            // can't happen; the backup manager service is local
17427        } catch (Exception e) {
17428            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
17429            e.printStackTrace();
17430        } finally {
17431            Binder.restoreCallingIdentity(oldIdent);
17432        }
17433    }
17434
17435    // done with this agent
17436    public void unbindBackupAgent(ApplicationInfo appInfo) {
17437        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
17438        if (appInfo == null) {
17439            Slog.w(TAG, "unbind backup agent for null app");
17440            return;
17441        }
17442
17443        synchronized(this) {
17444            try {
17445                if (mBackupAppName == null) {
17446                    Slog.w(TAG, "Unbinding backup agent with no active backup");
17447                    return;
17448                }
17449
17450                if (!mBackupAppName.equals(appInfo.packageName)) {
17451                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
17452                    return;
17453                }
17454
17455                // Not backing this app up any more; reset its OOM adjustment
17456                final ProcessRecord proc = mBackupTarget.app;
17457                updateOomAdjLocked(proc);
17458
17459                // If the app crashed during backup, 'thread' will be null here
17460                if (proc.thread != null) {
17461                    try {
17462                        proc.thread.scheduleDestroyBackupAgent(appInfo,
17463                                compatibilityInfoForPackageLocked(appInfo));
17464                    } catch (Exception e) {
17465                        Slog.e(TAG, "Exception when unbinding backup agent:");
17466                        e.printStackTrace();
17467                    }
17468                }
17469            } finally {
17470                mBackupTarget = null;
17471                mBackupAppName = null;
17472            }
17473        }
17474    }
17475    // =========================================================
17476    // BROADCASTS
17477    // =========================================================
17478
17479    boolean isPendingBroadcastProcessLocked(int pid) {
17480        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
17481                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
17482    }
17483
17484    void skipPendingBroadcastLocked(int pid) {
17485            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
17486            for (BroadcastQueue queue : mBroadcastQueues) {
17487                queue.skipPendingBroadcastLocked(pid);
17488            }
17489    }
17490
17491    // The app just attached; send any pending broadcasts that it should receive
17492    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
17493        boolean didSomething = false;
17494        for (BroadcastQueue queue : mBroadcastQueues) {
17495            didSomething |= queue.sendPendingBroadcastsLocked(app);
17496        }
17497        return didSomething;
17498    }
17499
17500    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
17501            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17502        enforceNotIsolatedCaller("registerReceiver");
17503        ArrayList<Intent> stickyIntents = null;
17504        ProcessRecord callerApp = null;
17505        int callingUid;
17506        int callingPid;
17507        synchronized(this) {
17508            if (caller != null) {
17509                callerApp = getRecordForAppLocked(caller);
17510                if (callerApp == null) {
17511                    throw new SecurityException(
17512                            "Unable to find app for caller " + caller
17513                            + " (pid=" + Binder.getCallingPid()
17514                            + ") when registering receiver " + receiver);
17515                }
17516                if (callerApp.info.uid != Process.SYSTEM_UID &&
17517                        !callerApp.pkgList.containsKey(callerPackage) &&
17518                        !"android".equals(callerPackage)) {
17519                    throw new SecurityException("Given caller package " + callerPackage
17520                            + " is not running in process " + callerApp);
17521                }
17522                callingUid = callerApp.info.uid;
17523                callingPid = callerApp.pid;
17524            } else {
17525                callerPackage = null;
17526                callingUid = Binder.getCallingUid();
17527                callingPid = Binder.getCallingPid();
17528            }
17529
17530            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17531                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17532
17533            Iterator<String> actions = filter.actionsIterator();
17534            if (actions == null) {
17535                ArrayList<String> noAction = new ArrayList<String>(1);
17536                noAction.add(null);
17537                actions = noAction.iterator();
17538            }
17539
17540            // Collect stickies of users
17541            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17542            while (actions.hasNext()) {
17543                String action = actions.next();
17544                for (int id : userIds) {
17545                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17546                    if (stickies != null) {
17547                        ArrayList<Intent> intents = stickies.get(action);
17548                        if (intents != null) {
17549                            if (stickyIntents == null) {
17550                                stickyIntents = new ArrayList<Intent>();
17551                            }
17552                            stickyIntents.addAll(intents);
17553                        }
17554                    }
17555                }
17556            }
17557        }
17558
17559        ArrayList<Intent> allSticky = null;
17560        if (stickyIntents != null) {
17561            final ContentResolver resolver = mContext.getContentResolver();
17562            // Look for any matching sticky broadcasts...
17563            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17564                Intent intent = stickyIntents.get(i);
17565                // If intent has scheme "content", it will need to acccess
17566                // provider that needs to lock mProviderMap in ActivityThread
17567                // and also it may need to wait application response, so we
17568                // cannot lock ActivityManagerService here.
17569                if (filter.match(resolver, intent, true, TAG) >= 0) {
17570                    if (allSticky == null) {
17571                        allSticky = new ArrayList<Intent>();
17572                    }
17573                    allSticky.add(intent);
17574                }
17575            }
17576        }
17577
17578        // The first sticky in the list is returned directly back to the client.
17579        Intent sticky = allSticky != null ? allSticky.get(0) : null;
17580        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17581        if (receiver == null) {
17582            return sticky;
17583        }
17584
17585        synchronized (this) {
17586            if (callerApp != null && (callerApp.thread == null
17587                    || callerApp.thread.asBinder() != caller.asBinder())) {
17588                // Original caller already died
17589                return null;
17590            }
17591            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17592            if (rl == null) {
17593                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17594                        userId, receiver);
17595                if (rl.app != null) {
17596                    rl.app.receivers.add(rl);
17597                } else {
17598                    try {
17599                        receiver.asBinder().linkToDeath(rl, 0);
17600                    } catch (RemoteException e) {
17601                        return sticky;
17602                    }
17603                    rl.linkedToDeath = true;
17604                }
17605                mRegisteredReceivers.put(receiver.asBinder(), rl);
17606            } else if (rl.uid != callingUid) {
17607                throw new IllegalArgumentException(
17608                        "Receiver requested to register for uid " + callingUid
17609                        + " was previously registered for uid " + rl.uid);
17610            } else if (rl.pid != callingPid) {
17611                throw new IllegalArgumentException(
17612                        "Receiver requested to register for pid " + callingPid
17613                        + " was previously registered for pid " + rl.pid);
17614            } else if (rl.userId != userId) {
17615                throw new IllegalArgumentException(
17616                        "Receiver requested to register for user " + userId
17617                        + " was previously registered for user " + rl.userId);
17618            }
17619            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17620                    permission, callingUid, userId);
17621            rl.add(bf);
17622            if (!bf.debugCheck()) {
17623                Slog.w(TAG, "==> For Dynamic broadcast");
17624            }
17625            mReceiverResolver.addFilter(bf);
17626
17627            // Enqueue broadcasts for all existing stickies that match
17628            // this filter.
17629            if (allSticky != null) {
17630                ArrayList receivers = new ArrayList();
17631                receivers.add(bf);
17632
17633                final int stickyCount = allSticky.size();
17634                for (int i = 0; i < stickyCount; i++) {
17635                    Intent intent = allSticky.get(i);
17636                    BroadcastQueue queue = broadcastQueueForIntent(intent);
17637                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17638                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17639                            null, 0, null, null, false, true, true, -1);
17640                    queue.enqueueParallelBroadcastLocked(r);
17641                    queue.scheduleBroadcastsLocked();
17642                }
17643            }
17644
17645            return sticky;
17646        }
17647    }
17648
17649    public void unregisterReceiver(IIntentReceiver receiver) {
17650        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17651
17652        final long origId = Binder.clearCallingIdentity();
17653        try {
17654            boolean doTrim = false;
17655
17656            synchronized(this) {
17657                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17658                if (rl != null) {
17659                    final BroadcastRecord r = rl.curBroadcast;
17660                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17661                        final boolean doNext = r.queue.finishReceiverLocked(
17662                                r, r.resultCode, r.resultData, r.resultExtras,
17663                                r.resultAbort, false);
17664                        if (doNext) {
17665                            doTrim = true;
17666                            r.queue.processNextBroadcast(false);
17667                        }
17668                    }
17669
17670                    if (rl.app != null) {
17671                        rl.app.receivers.remove(rl);
17672                    }
17673                    removeReceiverLocked(rl);
17674                    if (rl.linkedToDeath) {
17675                        rl.linkedToDeath = false;
17676                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
17677                    }
17678                }
17679            }
17680
17681            // If we actually concluded any broadcasts, we might now be able
17682            // to trim the recipients' apps from our working set
17683            if (doTrim) {
17684                trimApplications();
17685                return;
17686            }
17687
17688        } finally {
17689            Binder.restoreCallingIdentity(origId);
17690        }
17691    }
17692
17693    void removeReceiverLocked(ReceiverList rl) {
17694        mRegisteredReceivers.remove(rl.receiver.asBinder());
17695        for (int i = rl.size() - 1; i >= 0; i--) {
17696            mReceiverResolver.removeFilter(rl.get(i));
17697        }
17698    }
17699
17700    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17701        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17702            ProcessRecord r = mLruProcesses.get(i);
17703            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17704                try {
17705                    r.thread.dispatchPackageBroadcast(cmd, packages);
17706                } catch (RemoteException ex) {
17707                }
17708            }
17709        }
17710    }
17711
17712    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17713            int callingUid, int[] users) {
17714        // TODO: come back and remove this assumption to triage all broadcasts
17715        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17716
17717        List<ResolveInfo> receivers = null;
17718        try {
17719            HashSet<ComponentName> singleUserReceivers = null;
17720            boolean scannedFirstReceivers = false;
17721            for (int user : users) {
17722                // Skip users that have Shell restrictions, with exception of always permitted
17723                // Shell broadcasts
17724                if (callingUid == Process.SHELL_UID
17725                        && mUserController.hasUserRestriction(
17726                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17727                        && !isPermittedShellBroadcast(intent)) {
17728                    continue;
17729                }
17730                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17731                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17732                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17733                    // If this is not the system user, we need to check for
17734                    // any receivers that should be filtered out.
17735                    for (int i=0; i<newReceivers.size(); i++) {
17736                        ResolveInfo ri = newReceivers.get(i);
17737                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17738                            newReceivers.remove(i);
17739                            i--;
17740                        }
17741                    }
17742                }
17743                if (newReceivers != null && newReceivers.size() == 0) {
17744                    newReceivers = null;
17745                }
17746                if (receivers == null) {
17747                    receivers = newReceivers;
17748                } else if (newReceivers != null) {
17749                    // We need to concatenate the additional receivers
17750                    // found with what we have do far.  This would be easy,
17751                    // but we also need to de-dup any receivers that are
17752                    // singleUser.
17753                    if (!scannedFirstReceivers) {
17754                        // Collect any single user receivers we had already retrieved.
17755                        scannedFirstReceivers = true;
17756                        for (int i=0; i<receivers.size(); i++) {
17757                            ResolveInfo ri = receivers.get(i);
17758                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17759                                ComponentName cn = new ComponentName(
17760                                        ri.activityInfo.packageName, ri.activityInfo.name);
17761                                if (singleUserReceivers == null) {
17762                                    singleUserReceivers = new HashSet<ComponentName>();
17763                                }
17764                                singleUserReceivers.add(cn);
17765                            }
17766                        }
17767                    }
17768                    // Add the new results to the existing results, tracking
17769                    // and de-dupping single user receivers.
17770                    for (int i=0; i<newReceivers.size(); i++) {
17771                        ResolveInfo ri = newReceivers.get(i);
17772                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17773                            ComponentName cn = new ComponentName(
17774                                    ri.activityInfo.packageName, ri.activityInfo.name);
17775                            if (singleUserReceivers == null) {
17776                                singleUserReceivers = new HashSet<ComponentName>();
17777                            }
17778                            if (!singleUserReceivers.contains(cn)) {
17779                                singleUserReceivers.add(cn);
17780                                receivers.add(ri);
17781                            }
17782                        } else {
17783                            receivers.add(ri);
17784                        }
17785                    }
17786                }
17787            }
17788        } catch (RemoteException ex) {
17789            // pm is in same process, this will never happen.
17790        }
17791        return receivers;
17792    }
17793
17794    private boolean isPermittedShellBroadcast(Intent intent) {
17795        // remote bugreport should always be allowed to be taken
17796        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17797    }
17798
17799    private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
17800            String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
17801        final String action = intent.getAction();
17802        if (isProtectedBroadcast
17803                || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17804                || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17805                || Intent.ACTION_MEDIA_BUTTON.equals(action)
17806                || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17807                || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17808                || Intent.ACTION_MASTER_CLEAR.equals(action)
17809                || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17810                || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17811                || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
17812                || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
17813                || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
17814            // Broadcast is either protected, or it's a public action that
17815            // we've relaxed, so it's fine for system internals to send.
17816            return;
17817        }
17818
17819        // This broadcast may be a problem...  but there are often system components that
17820        // want to send an internal broadcast to themselves, which is annoying to have to
17821        // explicitly list each action as a protected broadcast, so we will check for that
17822        // one safe case and allow it: an explicit broadcast, only being received by something
17823        // that has protected itself.
17824        if (receivers != null && receivers.size() > 0
17825                && (intent.getPackage() != null || intent.getComponent() != null)) {
17826            boolean allProtected = true;
17827            for (int i = receivers.size()-1; i >= 0; i--) {
17828                Object target = receivers.get(i);
17829                if (target instanceof ResolveInfo) {
17830                    ResolveInfo ri = (ResolveInfo)target;
17831                    if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
17832                        allProtected = false;
17833                        break;
17834                    }
17835                } else {
17836                    BroadcastFilter bf = (BroadcastFilter)target;
17837                    if (bf.requiredPermission == null) {
17838                        allProtected = false;
17839                        break;
17840                    }
17841                }
17842            }
17843            if (allProtected) {
17844                // All safe!
17845                return;
17846            }
17847        }
17848
17849        // The vast majority of broadcasts sent from system internals
17850        // should be protected to avoid security holes, so yell loudly
17851        // to ensure we examine these cases.
17852        if (callerApp != null) {
17853            Log.wtf(TAG, "Sending non-protected broadcast " + action
17854                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
17855                    new Throwable());
17856        } else {
17857            Log.wtf(TAG, "Sending non-protected broadcast " + action
17858                            + " from system uid " + UserHandle.formatUid(callingUid)
17859                            + " pkg " + callerPackage,
17860                    new Throwable());
17861        }
17862    }
17863
17864    final int broadcastIntentLocked(ProcessRecord callerApp,
17865            String callerPackage, Intent intent, String resolvedType,
17866            IIntentReceiver resultTo, int resultCode, String resultData,
17867            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17868            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17869        intent = new Intent(intent);
17870
17871        // By default broadcasts do not go to stopped apps.
17872        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17873
17874        // If we have not finished booting, don't allow this to launch new processes.
17875        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17876            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17877        }
17878
17879        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17880                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17881                + " ordered=" + ordered + " userid=" + userId);
17882        if ((resultTo != null) && !ordered) {
17883            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17884        }
17885
17886        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17887                ALLOW_NON_FULL, "broadcast", callerPackage);
17888
17889        // Make sure that the user who is receiving this broadcast is running.
17890        // If not, we will just skip it. Make an exception for shutdown broadcasts
17891        // and upgrade steps.
17892
17893        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17894            if ((callingUid != Process.SYSTEM_UID
17895                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17896                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17897                Slog.w(TAG, "Skipping broadcast of " + intent
17898                        + ": user " + userId + " is stopped");
17899                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17900            }
17901        }
17902
17903        BroadcastOptions brOptions = null;
17904        if (bOptions != null) {
17905            brOptions = new BroadcastOptions(bOptions);
17906            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17907                // See if the caller is allowed to do this.  Note we are checking against
17908                // the actual real caller (not whoever provided the operation as say a
17909                // PendingIntent), because that who is actually supplied the arguments.
17910                if (checkComponentPermission(
17911                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17912                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17913                        != PackageManager.PERMISSION_GRANTED) {
17914                    String msg = "Permission Denial: " + intent.getAction()
17915                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17916                            + ", uid=" + callingUid + ")"
17917                            + " requires "
17918                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17919                    Slog.w(TAG, msg);
17920                    throw new SecurityException(msg);
17921                }
17922            }
17923        }
17924
17925        // Verify that protected broadcasts are only being sent by system code,
17926        // and that system code is only sending protected broadcasts.
17927        final String action = intent.getAction();
17928        final boolean isProtectedBroadcast;
17929        try {
17930            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17931        } catch (RemoteException e) {
17932            Slog.w(TAG, "Remote exception", e);
17933            return ActivityManager.BROADCAST_SUCCESS;
17934        }
17935
17936        final boolean isCallerSystem;
17937        switch (UserHandle.getAppId(callingUid)) {
17938            case Process.ROOT_UID:
17939            case Process.SYSTEM_UID:
17940            case Process.PHONE_UID:
17941            case Process.BLUETOOTH_UID:
17942            case Process.NFC_UID:
17943                isCallerSystem = true;
17944                break;
17945            default:
17946                isCallerSystem = (callerApp != null) && callerApp.persistent;
17947                break;
17948        }
17949
17950        // First line security check before anything else: stop non-system apps from
17951        // sending protected broadcasts.
17952        if (!isCallerSystem) {
17953            if (isProtectedBroadcast) {
17954                String msg = "Permission Denial: not allowed to send broadcast "
17955                        + action + " from pid="
17956                        + callingPid + ", uid=" + callingUid;
17957                Slog.w(TAG, msg);
17958                throw new SecurityException(msg);
17959
17960            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17961                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17962                // Special case for compatibility: we don't want apps to send this,
17963                // but historically it has not been protected and apps may be using it
17964                // to poke their own app widget.  So, instead of making it protected,
17965                // just limit it to the caller.
17966                if (callerPackage == null) {
17967                    String msg = "Permission Denial: not allowed to send broadcast "
17968                            + action + " from unknown caller.";
17969                    Slog.w(TAG, msg);
17970                    throw new SecurityException(msg);
17971                } else if (intent.getComponent() != null) {
17972                    // They are good enough to send to an explicit component...  verify
17973                    // it is being sent to the calling app.
17974                    if (!intent.getComponent().getPackageName().equals(
17975                            callerPackage)) {
17976                        String msg = "Permission Denial: not allowed to send broadcast "
17977                                + action + " to "
17978                                + intent.getComponent().getPackageName() + " from "
17979                                + callerPackage;
17980                        Slog.w(TAG, msg);
17981                        throw new SecurityException(msg);
17982                    }
17983                } else {
17984                    // Limit broadcast to their own package.
17985                    intent.setPackage(callerPackage);
17986                }
17987            }
17988        }
17989
17990        if (action != null) {
17991            switch (action) {
17992                case Intent.ACTION_UID_REMOVED:
17993                case Intent.ACTION_PACKAGE_REMOVED:
17994                case Intent.ACTION_PACKAGE_CHANGED:
17995                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17996                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17997                case Intent.ACTION_PACKAGES_SUSPENDED:
17998                case Intent.ACTION_PACKAGES_UNSUSPENDED:
17999                    // Handle special intents: if this broadcast is from the package
18000                    // manager about a package being removed, we need to remove all of
18001                    // its activities from the history stack.
18002                    if (checkComponentPermission(
18003                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
18004                            callingPid, callingUid, -1, true)
18005                            != PackageManager.PERMISSION_GRANTED) {
18006                        String msg = "Permission Denial: " + intent.getAction()
18007                                + " broadcast from " + callerPackage + " (pid=" + callingPid
18008                                + ", uid=" + callingUid + ")"
18009                                + " requires "
18010                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
18011                        Slog.w(TAG, msg);
18012                        throw new SecurityException(msg);
18013                    }
18014                    switch (action) {
18015                        case Intent.ACTION_UID_REMOVED:
18016                            final Bundle intentExtras = intent.getExtras();
18017                            final int uid = intentExtras != null
18018                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
18019                            if (uid >= 0) {
18020                                mBatteryStatsService.removeUid(uid);
18021                                mAppOpsService.uidRemoved(uid);
18022                            }
18023                            break;
18024                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
18025                            // If resources are unavailable just force stop all those packages
18026                            // and flush the attribute cache as well.
18027                            String list[] =
18028                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18029                            if (list != null && list.length > 0) {
18030                                for (int i = 0; i < list.length; i++) {
18031                                    forceStopPackageLocked(list[i], -1, false, true, true,
18032                                            false, false, userId, "storage unmount");
18033                                }
18034                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
18035                                sendPackageBroadcastLocked(
18036                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
18037                                        userId);
18038                            }
18039                            break;
18040                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
18041                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
18042                            break;
18043                        case Intent.ACTION_PACKAGE_REMOVED:
18044                        case Intent.ACTION_PACKAGE_CHANGED:
18045                            Uri data = intent.getData();
18046                            String ssp;
18047                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
18048                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
18049                                final boolean replacing =
18050                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
18051                                final boolean killProcess =
18052                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
18053                                final boolean fullUninstall = removed && !replacing;
18054                                if (removed) {
18055                                    if (killProcess) {
18056                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
18057                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
18058                                                false, true, true, false, fullUninstall, userId,
18059                                                removed ? "pkg removed" : "pkg changed");
18060                                    }
18061                                    final int cmd = killProcess
18062                                            ? IApplicationThread.PACKAGE_REMOVED
18063                                            : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
18064                                    sendPackageBroadcastLocked(cmd,
18065                                            new String[] {ssp}, userId);
18066                                    if (fullUninstall) {
18067                                        mAppOpsService.packageRemoved(
18068                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
18069
18070                                        // Remove all permissions granted from/to this package
18071                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
18072
18073                                        removeTasksByPackageNameLocked(ssp, userId);
18074
18075                                        // Hide the "unsupported display" dialog if necessary.
18076                                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
18077                                                mUnsupportedDisplaySizeDialog.getPackageName())) {
18078                                            mUnsupportedDisplaySizeDialog.dismiss();
18079                                            mUnsupportedDisplaySizeDialog = null;
18080                                        }
18081                                        mCompatModePackages.handlePackageUninstalledLocked(ssp);
18082                                        mBatteryStatsService.notePackageUninstalled(ssp);
18083                                    }
18084                                } else {
18085                                    if (killProcess) {
18086                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
18087                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
18088                                                userId, ProcessList.INVALID_ADJ,
18089                                                false, true, true, false, "change " + ssp);
18090                                    }
18091                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
18092                                            intent.getStringArrayExtra(
18093                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
18094                                }
18095                            }
18096                            break;
18097                        case Intent.ACTION_PACKAGES_SUSPENDED:
18098                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
18099                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
18100                                    intent.getAction());
18101                            final String[] packageNames = intent.getStringArrayExtra(
18102                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
18103                            final int userHandle = intent.getIntExtra(
18104                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
18105
18106                            synchronized(ActivityManagerService.this) {
18107                                mRecentTasks.onPackagesSuspendedChanged(
18108                                        packageNames, suspended, userHandle);
18109                            }
18110                            break;
18111                    }
18112                    break;
18113                case Intent.ACTION_PACKAGE_REPLACED:
18114                {
18115                    final Uri data = intent.getData();
18116                    final String ssp;
18117                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18118                        final ApplicationInfo aInfo =
18119                                getPackageManagerInternalLocked().getApplicationInfo(
18120                                        ssp,
18121                                        userId);
18122                        if (aInfo == null) {
18123                            Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
18124                                    + " ssp=" + ssp + " data=" + data);
18125                            return ActivityManager.BROADCAST_SUCCESS;
18126                        }
18127                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
18128                        sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
18129                                new String[] {ssp}, userId);
18130                    }
18131                    break;
18132                }
18133                case Intent.ACTION_PACKAGE_ADDED:
18134                {
18135                    // Special case for adding a package: by default turn on compatibility mode.
18136                    Uri data = intent.getData();
18137                    String ssp;
18138                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18139                        final boolean replacing =
18140                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
18141                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
18142
18143                        try {
18144                            ApplicationInfo ai = AppGlobals.getPackageManager().
18145                                    getApplicationInfo(ssp, 0, 0);
18146                            mBatteryStatsService.notePackageInstalled(ssp,
18147                                    ai != null ? ai.versionCode : 0);
18148                        } catch (RemoteException e) {
18149                        }
18150                    }
18151                    break;
18152                }
18153                case Intent.ACTION_PACKAGE_DATA_CLEARED:
18154                {
18155                    Uri data = intent.getData();
18156                    String ssp;
18157                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18158                        // Hide the "unsupported display" dialog if necessary.
18159                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
18160                                mUnsupportedDisplaySizeDialog.getPackageName())) {
18161                            mUnsupportedDisplaySizeDialog.dismiss();
18162                            mUnsupportedDisplaySizeDialog = null;
18163                        }
18164                        mCompatModePackages.handlePackageDataClearedLocked(ssp);
18165                    }
18166                    break;
18167                }
18168                case Intent.ACTION_TIMEZONE_CHANGED:
18169                    // If this is the time zone changed action, queue up a message that will reset
18170                    // the timezone of all currently running processes. This message will get
18171                    // queued up before the broadcast happens.
18172                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
18173                    break;
18174                case Intent.ACTION_TIME_CHANGED:
18175                    // If the user set the time, let all running processes know.
18176                    final int is24Hour =
18177                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
18178                                    : 0;
18179                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
18180                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18181                    synchronized (stats) {
18182                        stats.noteCurrentTimeChangedLocked();
18183                    }
18184                    break;
18185                case Intent.ACTION_CLEAR_DNS_CACHE:
18186                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
18187                    break;
18188                case Proxy.PROXY_CHANGE_ACTION:
18189                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
18190                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
18191                    break;
18192                case android.hardware.Camera.ACTION_NEW_PICTURE:
18193                case android.hardware.Camera.ACTION_NEW_VIDEO:
18194                    // These broadcasts are no longer allowed by the system, since they can
18195                    // cause significant thrashing at a crictical point (using the camera).
18196                    // Apps should use JobScehduler to monitor for media provider changes.
18197                    Slog.w(TAG, action + " no longer allowed; dropping from "
18198                            + UserHandle.formatUid(callingUid));
18199                    if (resultTo != null) {
18200                        final BroadcastQueue queue = broadcastQueueForIntent(intent);
18201                        try {
18202                            queue.performReceiveLocked(callerApp, resultTo, intent,
18203                                    Activity.RESULT_CANCELED, null, null,
18204                                    false, false, userId);
18205                        } catch (RemoteException e) {
18206                            Slog.w(TAG, "Failure ["
18207                                    + queue.mQueueName + "] sending broadcast result of "
18208                                    + intent, e);
18209
18210                        }
18211                    }
18212                    // Lie; we don't want to crash the app.
18213                    return ActivityManager.BROADCAST_SUCCESS;
18214            }
18215        }
18216
18217        // Add to the sticky list if requested.
18218        if (sticky) {
18219            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
18220                    callingPid, callingUid)
18221                    != PackageManager.PERMISSION_GRANTED) {
18222                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
18223                        + callingPid + ", uid=" + callingUid
18224                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18225                Slog.w(TAG, msg);
18226                throw new SecurityException(msg);
18227            }
18228            if (requiredPermissions != null && requiredPermissions.length > 0) {
18229                Slog.w(TAG, "Can't broadcast sticky intent " + intent
18230                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
18231                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
18232            }
18233            if (intent.getComponent() != null) {
18234                throw new SecurityException(
18235                        "Sticky broadcasts can't target a specific component");
18236            }
18237            // We use userId directly here, since the "all" target is maintained
18238            // as a separate set of sticky broadcasts.
18239            if (userId != UserHandle.USER_ALL) {
18240                // But first, if this is not a broadcast to all users, then
18241                // make sure it doesn't conflict with an existing broadcast to
18242                // all users.
18243                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
18244                        UserHandle.USER_ALL);
18245                if (stickies != null) {
18246                    ArrayList<Intent> list = stickies.get(intent.getAction());
18247                    if (list != null) {
18248                        int N = list.size();
18249                        int i;
18250                        for (i=0; i<N; i++) {
18251                            if (intent.filterEquals(list.get(i))) {
18252                                throw new IllegalArgumentException(
18253                                        "Sticky broadcast " + intent + " for user "
18254                                        + userId + " conflicts with existing global broadcast");
18255                            }
18256                        }
18257                    }
18258                }
18259            }
18260            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18261            if (stickies == null) {
18262                stickies = new ArrayMap<>();
18263                mStickyBroadcasts.put(userId, stickies);
18264            }
18265            ArrayList<Intent> list = stickies.get(intent.getAction());
18266            if (list == null) {
18267                list = new ArrayList<>();
18268                stickies.put(intent.getAction(), list);
18269            }
18270            final int stickiesCount = list.size();
18271            int i;
18272            for (i = 0; i < stickiesCount; i++) {
18273                if (intent.filterEquals(list.get(i))) {
18274                    // This sticky already exists, replace it.
18275                    list.set(i, new Intent(intent));
18276                    break;
18277                }
18278            }
18279            if (i >= stickiesCount) {
18280                list.add(new Intent(intent));
18281            }
18282        }
18283
18284        int[] users;
18285        if (userId == UserHandle.USER_ALL) {
18286            // Caller wants broadcast to go to all started users.
18287            users = mUserController.getStartedUserArrayLocked();
18288        } else {
18289            // Caller wants broadcast to go to one specific user.
18290            users = new int[] {userId};
18291        }
18292
18293        // Figure out who all will receive this broadcast.
18294        List receivers = null;
18295        List<BroadcastFilter> registeredReceivers = null;
18296        // Need to resolve the intent to interested receivers...
18297        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
18298                 == 0) {
18299            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
18300        }
18301        if (intent.getComponent() == null) {
18302            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
18303                // Query one target user at a time, excluding shell-restricted users
18304                for (int i = 0; i < users.length; i++) {
18305                    if (mUserController.hasUserRestriction(
18306                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
18307                        continue;
18308                    }
18309                    List<BroadcastFilter> registeredReceiversForUser =
18310                            mReceiverResolver.queryIntent(intent,
18311                                    resolvedType, false, users[i]);
18312                    if (registeredReceivers == null) {
18313                        registeredReceivers = registeredReceiversForUser;
18314                    } else if (registeredReceiversForUser != null) {
18315                        registeredReceivers.addAll(registeredReceiversForUser);
18316                    }
18317                }
18318            } else {
18319                registeredReceivers = mReceiverResolver.queryIntent(intent,
18320                        resolvedType, false, userId);
18321            }
18322        }
18323
18324        final boolean replacePending =
18325                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
18326
18327        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
18328                + " replacePending=" + replacePending);
18329
18330        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
18331        if (!ordered && NR > 0) {
18332            // If we are not serializing this broadcast, then send the
18333            // registered receivers separately so they don't wait for the
18334            // components to be launched.
18335            if (isCallerSystem) {
18336                checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
18337                        isProtectedBroadcast, registeredReceivers);
18338            }
18339            final BroadcastQueue queue = broadcastQueueForIntent(intent);
18340            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18341                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
18342                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
18343                    resultExtras, ordered, sticky, false, userId);
18344            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
18345            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
18346            if (!replaced) {
18347                queue.enqueueParallelBroadcastLocked(r);
18348                queue.scheduleBroadcastsLocked();
18349            }
18350            registeredReceivers = null;
18351            NR = 0;
18352        }
18353
18354        // Merge into one list.
18355        int ir = 0;
18356        if (receivers != null) {
18357            // A special case for PACKAGE_ADDED: do not allow the package
18358            // being added to see this broadcast.  This prevents them from
18359            // using this as a back door to get run as soon as they are
18360            // installed.  Maybe in the future we want to have a special install
18361            // broadcast or such for apps, but we'd like to deliberately make
18362            // this decision.
18363            String skipPackages[] = null;
18364            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
18365                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
18366                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
18367                Uri data = intent.getData();
18368                if (data != null) {
18369                    String pkgName = data.getSchemeSpecificPart();
18370                    if (pkgName != null) {
18371                        skipPackages = new String[] { pkgName };
18372                    }
18373                }
18374            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
18375                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18376            }
18377            if (skipPackages != null && (skipPackages.length > 0)) {
18378                for (String skipPackage : skipPackages) {
18379                    if (skipPackage != null) {
18380                        int NT = receivers.size();
18381                        for (int it=0; it<NT; it++) {
18382                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
18383                            if (curt.activityInfo.packageName.equals(skipPackage)) {
18384                                receivers.remove(it);
18385                                it--;
18386                                NT--;
18387                            }
18388                        }
18389                    }
18390                }
18391            }
18392
18393            int NT = receivers != null ? receivers.size() : 0;
18394            int it = 0;
18395            ResolveInfo curt = null;
18396            BroadcastFilter curr = null;
18397            while (it < NT && ir < NR) {
18398                if (curt == null) {
18399                    curt = (ResolveInfo)receivers.get(it);
18400                }
18401                if (curr == null) {
18402                    curr = registeredReceivers.get(ir);
18403                }
18404                if (curr.getPriority() >= curt.priority) {
18405                    // Insert this broadcast record into the final list.
18406                    receivers.add(it, curr);
18407                    ir++;
18408                    curr = null;
18409                    it++;
18410                    NT++;
18411                } else {
18412                    // Skip to the next ResolveInfo in the final list.
18413                    it++;
18414                    curt = null;
18415                }
18416            }
18417        }
18418        while (ir < NR) {
18419            if (receivers == null) {
18420                receivers = new ArrayList();
18421            }
18422            receivers.add(registeredReceivers.get(ir));
18423            ir++;
18424        }
18425
18426        if (isCallerSystem) {
18427            checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
18428                    isProtectedBroadcast, receivers);
18429        }
18430
18431        if ((receivers != null && receivers.size() > 0)
18432                || resultTo != null) {
18433            BroadcastQueue queue = broadcastQueueForIntent(intent);
18434            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18435                    callerPackage, callingPid, callingUid, resolvedType,
18436                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
18437                    resultData, resultExtras, ordered, sticky, false, userId);
18438
18439            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
18440                    + ": prev had " + queue.mOrderedBroadcasts.size());
18441            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
18442                    "Enqueueing broadcast " + r.intent.getAction());
18443
18444            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
18445            if (!replaced) {
18446                queue.enqueueOrderedBroadcastLocked(r);
18447                queue.scheduleBroadcastsLocked();
18448            }
18449        } else {
18450            // There was nobody interested in the broadcast, but we still want to record
18451            // that it happened.
18452            if (intent.getComponent() == null && intent.getPackage() == null
18453                    && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18454                // This was an implicit broadcast... let's record it for posterity.
18455                addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
18456            }
18457        }
18458
18459        return ActivityManager.BROADCAST_SUCCESS;
18460    }
18461
18462    final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
18463            int skipCount, long dispatchTime) {
18464        final long now = SystemClock.elapsedRealtime();
18465        if (mCurBroadcastStats == null ||
18466                (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
18467            mLastBroadcastStats = mCurBroadcastStats;
18468            if (mLastBroadcastStats != null) {
18469                mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
18470                mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
18471            }
18472            mCurBroadcastStats = new BroadcastStats();
18473        }
18474        mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
18475    }
18476
18477    final Intent verifyBroadcastLocked(Intent intent) {
18478        // Refuse possible leaked file descriptors
18479        if (intent != null && intent.hasFileDescriptors() == true) {
18480            throw new IllegalArgumentException("File descriptors passed in Intent");
18481        }
18482
18483        int flags = intent.getFlags();
18484
18485        if (!mProcessesReady) {
18486            // if the caller really truly claims to know what they're doing, go
18487            // ahead and allow the broadcast without launching any receivers
18488            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
18489                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
18490            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18491                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
18492                        + " before boot completion");
18493                throw new IllegalStateException("Cannot broadcast before boot completed");
18494            }
18495        }
18496
18497        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
18498            throw new IllegalArgumentException(
18499                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
18500        }
18501
18502        return intent;
18503    }
18504
18505    public final int broadcastIntent(IApplicationThread caller,
18506            Intent intent, String resolvedType, IIntentReceiver resultTo,
18507            int resultCode, String resultData, Bundle resultExtras,
18508            String[] requiredPermissions, int appOp, Bundle bOptions,
18509            boolean serialized, boolean sticky, int userId) {
18510        enforceNotIsolatedCaller("broadcastIntent");
18511        synchronized(this) {
18512            intent = verifyBroadcastLocked(intent);
18513
18514            final ProcessRecord callerApp = getRecordForAppLocked(caller);
18515            final int callingPid = Binder.getCallingPid();
18516            final int callingUid = Binder.getCallingUid();
18517            final long origId = Binder.clearCallingIdentity();
18518            int res = broadcastIntentLocked(callerApp,
18519                    callerApp != null ? callerApp.info.packageName : null,
18520                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
18521                    requiredPermissions, appOp, bOptions, serialized, sticky,
18522                    callingPid, callingUid, userId);
18523            Binder.restoreCallingIdentity(origId);
18524            return res;
18525        }
18526    }
18527
18528
18529    int broadcastIntentInPackage(String packageName, int uid,
18530            Intent intent, String resolvedType, IIntentReceiver resultTo,
18531            int resultCode, String resultData, Bundle resultExtras,
18532            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
18533            int userId) {
18534        synchronized(this) {
18535            intent = verifyBroadcastLocked(intent);
18536
18537            final long origId = Binder.clearCallingIdentity();
18538            String[] requiredPermissions = requiredPermission == null ? null
18539                    : new String[] {requiredPermission};
18540            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
18541                    resultTo, resultCode, resultData, resultExtras,
18542                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
18543                    sticky, -1, uid, userId);
18544            Binder.restoreCallingIdentity(origId);
18545            return res;
18546        }
18547    }
18548
18549    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
18550        // Refuse possible leaked file descriptors
18551        if (intent != null && intent.hasFileDescriptors() == true) {
18552            throw new IllegalArgumentException("File descriptors passed in Intent");
18553        }
18554
18555        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18556                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
18557
18558        synchronized(this) {
18559            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
18560                    != PackageManager.PERMISSION_GRANTED) {
18561                String msg = "Permission Denial: unbroadcastIntent() from pid="
18562                        + Binder.getCallingPid()
18563                        + ", uid=" + Binder.getCallingUid()
18564                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18565                Slog.w(TAG, msg);
18566                throw new SecurityException(msg);
18567            }
18568            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18569            if (stickies != null) {
18570                ArrayList<Intent> list = stickies.get(intent.getAction());
18571                if (list != null) {
18572                    int N = list.size();
18573                    int i;
18574                    for (i=0; i<N; i++) {
18575                        if (intent.filterEquals(list.get(i))) {
18576                            list.remove(i);
18577                            break;
18578                        }
18579                    }
18580                    if (list.size() <= 0) {
18581                        stickies.remove(intent.getAction());
18582                    }
18583                }
18584                if (stickies.size() <= 0) {
18585                    mStickyBroadcasts.remove(userId);
18586                }
18587            }
18588        }
18589    }
18590
18591    void backgroundServicesFinishedLocked(int userId) {
18592        for (BroadcastQueue queue : mBroadcastQueues) {
18593            queue.backgroundServicesFinishedLocked(userId);
18594        }
18595    }
18596
18597    public void finishReceiver(IBinder who, int resultCode, String resultData,
18598            Bundle resultExtras, boolean resultAbort, int flags) {
18599        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
18600
18601        // Refuse possible leaked file descriptors
18602        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
18603            throw new IllegalArgumentException("File descriptors passed in Bundle");
18604        }
18605
18606        final long origId = Binder.clearCallingIdentity();
18607        try {
18608            boolean doNext = false;
18609            BroadcastRecord r;
18610
18611            synchronized(this) {
18612                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
18613                        ? mFgBroadcastQueue : mBgBroadcastQueue;
18614                r = queue.getMatchingOrderedReceiver(who);
18615                if (r != null) {
18616                    doNext = r.queue.finishReceiverLocked(r, resultCode,
18617                        resultData, resultExtras, resultAbort, true);
18618                }
18619            }
18620
18621            if (doNext) {
18622                r.queue.processNextBroadcast(false);
18623            }
18624            trimApplications();
18625        } finally {
18626            Binder.restoreCallingIdentity(origId);
18627        }
18628    }
18629
18630    // =========================================================
18631    // INSTRUMENTATION
18632    // =========================================================
18633
18634    public boolean startInstrumentation(ComponentName className,
18635            String profileFile, int flags, Bundle arguments,
18636            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
18637            int userId, String abiOverride) {
18638        enforceNotIsolatedCaller("startInstrumentation");
18639        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18640                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
18641        // Refuse possible leaked file descriptors
18642        if (arguments != null && arguments.hasFileDescriptors()) {
18643            throw new IllegalArgumentException("File descriptors passed in Bundle");
18644        }
18645
18646        synchronized(this) {
18647            InstrumentationInfo ii = null;
18648            ApplicationInfo ai = null;
18649            try {
18650                ii = mContext.getPackageManager().getInstrumentationInfo(
18651                    className, STOCK_PM_FLAGS);
18652                ai = AppGlobals.getPackageManager().getApplicationInfo(
18653                        ii.targetPackage, STOCK_PM_FLAGS, userId);
18654            } catch (PackageManager.NameNotFoundException e) {
18655            } catch (RemoteException e) {
18656            }
18657            if (ii == null) {
18658                reportStartInstrumentationFailureLocked(watcher, className,
18659                        "Unable to find instrumentation info for: " + className);
18660                return false;
18661            }
18662            if (ai == null) {
18663                reportStartInstrumentationFailureLocked(watcher, className,
18664                        "Unable to find instrumentation target package: " + ii.targetPackage);
18665                return false;
18666            }
18667            if (!ai.hasCode()) {
18668                reportStartInstrumentationFailureLocked(watcher, className,
18669                        "Instrumentation target has no code: " + ii.targetPackage);
18670                return false;
18671            }
18672
18673            int match = mContext.getPackageManager().checkSignatures(
18674                    ii.targetPackage, ii.packageName);
18675            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18676                String msg = "Permission Denial: starting instrumentation "
18677                        + className + " from pid="
18678                        + Binder.getCallingPid()
18679                        + ", uid=" + Binder.getCallingPid()
18680                        + " not allowed because package " + ii.packageName
18681                        + " does not have a signature matching the target "
18682                        + ii.targetPackage;
18683                reportStartInstrumentationFailureLocked(watcher, className, msg);
18684                throw new SecurityException(msg);
18685            }
18686
18687            final long origId = Binder.clearCallingIdentity();
18688            // Instrumentation can kill and relaunch even persistent processes
18689            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18690                    "start instr");
18691            ProcessRecord app = addAppLocked(ai, false, abiOverride);
18692            app.instrumentationClass = className;
18693            app.instrumentationInfo = ai;
18694            app.instrumentationProfileFile = profileFile;
18695            app.instrumentationArguments = arguments;
18696            app.instrumentationWatcher = watcher;
18697            app.instrumentationUiAutomationConnection = uiAutomationConnection;
18698            app.instrumentationResultClass = className;
18699            Binder.restoreCallingIdentity(origId);
18700        }
18701
18702        return true;
18703    }
18704
18705    /**
18706     * Report errors that occur while attempting to start Instrumentation.  Always writes the
18707     * error to the logs, but if somebody is watching, send the report there too.  This enables
18708     * the "am" command to report errors with more information.
18709     *
18710     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
18711     * @param cn The component name of the instrumentation.
18712     * @param report The error report.
18713     */
18714    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18715            ComponentName cn, String report) {
18716        Slog.w(TAG, report);
18717        if (watcher != null) {
18718            Bundle results = new Bundle();
18719            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18720            results.putString("Error", report);
18721            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18722        }
18723    }
18724
18725    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18726        if (app.instrumentationWatcher != null) {
18727            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18728                    app.instrumentationClass, resultCode, results);
18729        }
18730
18731        // Can't call out of the system process with a lock held, so post a message.
18732        if (app.instrumentationUiAutomationConnection != null) {
18733            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18734                    app.instrumentationUiAutomationConnection).sendToTarget();
18735        }
18736
18737        app.instrumentationWatcher = null;
18738        app.instrumentationUiAutomationConnection = null;
18739        app.instrumentationClass = null;
18740        app.instrumentationInfo = null;
18741        app.instrumentationProfileFile = null;
18742        app.instrumentationArguments = null;
18743
18744        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18745                "finished inst");
18746    }
18747
18748    public void finishInstrumentation(IApplicationThread target,
18749            int resultCode, Bundle results) {
18750        int userId = UserHandle.getCallingUserId();
18751        // Refuse possible leaked file descriptors
18752        if (results != null && results.hasFileDescriptors()) {
18753            throw new IllegalArgumentException("File descriptors passed in Intent");
18754        }
18755
18756        synchronized(this) {
18757            ProcessRecord app = getRecordForAppLocked(target);
18758            if (app == null) {
18759                Slog.w(TAG, "finishInstrumentation: no app for " + target);
18760                return;
18761            }
18762            final long origId = Binder.clearCallingIdentity();
18763            finishInstrumentationLocked(app, resultCode, results);
18764            Binder.restoreCallingIdentity(origId);
18765        }
18766    }
18767
18768    // =========================================================
18769    // CONFIGURATION
18770    // =========================================================
18771
18772    public ConfigurationInfo getDeviceConfigurationInfo() {
18773        ConfigurationInfo config = new ConfigurationInfo();
18774        synchronized (this) {
18775            config.reqTouchScreen = mConfiguration.touchscreen;
18776            config.reqKeyboardType = mConfiguration.keyboard;
18777            config.reqNavigation = mConfiguration.navigation;
18778            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18779                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18780                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18781            }
18782            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18783                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18784                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18785            }
18786            config.reqGlEsVersion = GL_ES_VERSION;
18787        }
18788        return config;
18789    }
18790
18791    ActivityStack getFocusedStack() {
18792        return mStackSupervisor.getFocusedStack();
18793    }
18794
18795    @Override
18796    public int getFocusedStackId() throws RemoteException {
18797        ActivityStack focusedStack = getFocusedStack();
18798        if (focusedStack != null) {
18799            return focusedStack.getStackId();
18800        }
18801        return -1;
18802    }
18803
18804    public Configuration getConfiguration() {
18805        Configuration ci;
18806        synchronized(this) {
18807            ci = new Configuration(mConfiguration);
18808            ci.userSetLocale = false;
18809        }
18810        return ci;
18811    }
18812
18813    @Override
18814    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18815        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18816        synchronized (this) {
18817            mSuppressResizeConfigChanges = suppress;
18818        }
18819    }
18820
18821    @Override
18822    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18823        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18824        if (fromStackId == HOME_STACK_ID) {
18825            throw new IllegalArgumentException("You can't move tasks from the home stack.");
18826        }
18827        synchronized (this) {
18828            final long origId = Binder.clearCallingIdentity();
18829            try {
18830                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18831            } finally {
18832                Binder.restoreCallingIdentity(origId);
18833            }
18834        }
18835    }
18836
18837    @Override
18838    public void updatePersistentConfiguration(Configuration values) {
18839        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18840                "updateConfiguration()");
18841        enforceWriteSettingsPermission("updateConfiguration()");
18842        if (values == null) {
18843            throw new NullPointerException("Configuration must not be null");
18844        }
18845
18846        int userId = UserHandle.getCallingUserId();
18847
18848        synchronized(this) {
18849            updatePersistentConfigurationLocked(values, userId);
18850        }
18851    }
18852
18853    private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
18854        final long origId = Binder.clearCallingIdentity();
18855        try {
18856            updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
18857        } finally {
18858            Binder.restoreCallingIdentity(origId);
18859        }
18860    }
18861
18862    private void updateFontScaleIfNeeded(@UserIdInt int userId) {
18863        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18864                FONT_SCALE, 1.0f, userId);
18865        if (mConfiguration.fontScale != scaleFactor) {
18866            final Configuration configuration = mWindowManager.computeNewConfiguration();
18867            configuration.fontScale = scaleFactor;
18868            synchronized (this) {
18869                updatePersistentConfigurationLocked(configuration, userId);
18870            }
18871        }
18872    }
18873
18874    private void enforceWriteSettingsPermission(String func) {
18875        int uid = Binder.getCallingUid();
18876        if (uid == Process.ROOT_UID) {
18877            return;
18878        }
18879
18880        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18881                Settings.getPackageNameForUid(mContext, uid), false)) {
18882            return;
18883        }
18884
18885        String msg = "Permission Denial: " + func + " from pid="
18886                + Binder.getCallingPid()
18887                + ", uid=" + uid
18888                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18889        Slog.w(TAG, msg);
18890        throw new SecurityException(msg);
18891    }
18892
18893    public void updateConfiguration(Configuration values) {
18894        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18895                "updateConfiguration()");
18896
18897        synchronized(this) {
18898            if (values == null && mWindowManager != null) {
18899                // sentinel: fetch the current configuration from the window manager
18900                values = mWindowManager.computeNewConfiguration();
18901            }
18902
18903            if (mWindowManager != null) {
18904                mProcessList.applyDisplaySize(mWindowManager);
18905            }
18906
18907            final long origId = Binder.clearCallingIdentity();
18908            if (values != null) {
18909                Settings.System.clearConfiguration(values);
18910            }
18911            updateConfigurationLocked(values, null, false);
18912            Binder.restoreCallingIdentity(origId);
18913        }
18914    }
18915
18916    void updateUserConfigurationLocked() {
18917        Configuration configuration = new Configuration(mConfiguration);
18918        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
18919                mUserController.getCurrentUserIdLocked(), Settings.System.canWrite(mContext));
18920        updateConfigurationLocked(configuration, null, false);
18921    }
18922
18923    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
18924            boolean initLocale) {
18925        return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
18926    }
18927
18928    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
18929            boolean initLocale, boolean deferResume) {
18930        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18931        return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
18932                UserHandle.USER_NULL, deferResume);
18933    }
18934
18935    // To cache the list of supported system locales
18936    private String[] mSupportedSystemLocales = null;
18937
18938    /**
18939     * Do either or both things: (1) change the current configuration, and (2)
18940     * make sure the given activity is running with the (now) current
18941     * configuration.  Returns true if the activity has been left running, or
18942     * false if <var>starting</var> is being destroyed to match the new
18943     * configuration.
18944     *
18945     * @param userId is only used when persistent parameter is set to true to persist configuration
18946     *               for that particular user
18947     */
18948    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
18949            boolean initLocale, boolean persistent, int userId, boolean deferResume) {
18950        int changes = 0;
18951
18952        if (mWindowManager != null) {
18953            mWindowManager.deferSurfaceLayout();
18954        }
18955        if (values != null) {
18956            Configuration newConfig = new Configuration(mConfiguration);
18957            changes = newConfig.updateFrom(values);
18958            if (changes != 0) {
18959                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18960                        "Updating configuration to: " + values);
18961
18962                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18963
18964                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18965                    final LocaleList locales = values.getLocales();
18966                    int bestLocaleIndex = 0;
18967                    if (locales.size() > 1) {
18968                        if (mSupportedSystemLocales == null) {
18969                            mSupportedSystemLocales =
18970                                    Resources.getSystem().getAssets().getLocales();
18971                        }
18972                        bestLocaleIndex = Math.max(0,
18973                                locales.getFirstMatchIndex(mSupportedSystemLocales));
18974                    }
18975                    SystemProperties.set("persist.sys.locale",
18976                            locales.get(bestLocaleIndex).toLanguageTag());
18977                    LocaleList.setDefault(locales, bestLocaleIndex);
18978                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18979                            locales.get(bestLocaleIndex)));
18980                }
18981
18982                mConfigurationSeq++;
18983                if (mConfigurationSeq <= 0) {
18984                    mConfigurationSeq = 1;
18985                }
18986                newConfig.seq = mConfigurationSeq;
18987                mConfiguration = newConfig;
18988                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18989                mUsageStatsService.reportConfigurationChange(newConfig,
18990                        mUserController.getCurrentUserIdLocked());
18991                //mUsageStatsService.noteStartConfig(newConfig);
18992
18993                final Configuration configCopy = new Configuration(mConfiguration);
18994
18995                // TODO: If our config changes, should we auto dismiss any currently
18996                // showing dialogs?
18997                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18998
18999                AttributeCache ac = AttributeCache.instance();
19000                if (ac != null) {
19001                    ac.updateConfiguration(configCopy);
19002                }
19003
19004                // Make sure all resources in our process are updated
19005                // right now, so that anyone who is going to retrieve
19006                // resource values after we return will be sure to get
19007                // the new ones.  This is especially important during
19008                // boot, where the first config change needs to guarantee
19009                // all resources have that config before following boot
19010                // code is executed.
19011                mSystemThread.applyConfigurationToResources(configCopy);
19012
19013                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
19014                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
19015                    msg.obj = new Configuration(configCopy);
19016                    msg.arg1 = userId;
19017                    mHandler.sendMessage(msg);
19018                }
19019
19020                final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
19021                if (isDensityChange) {
19022                    // Reset the unsupported display size dialog.
19023                    mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
19024
19025                    killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
19026                            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
19027                }
19028
19029                for (int i=mLruProcesses.size()-1; i>=0; i--) {
19030                    ProcessRecord app = mLruProcesses.get(i);
19031                    try {
19032                        if (app.thread != null) {
19033                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
19034                                    + app.processName + " new config " + mConfiguration);
19035                            app.thread.scheduleConfigurationChanged(configCopy);
19036                        }
19037                    } catch (Exception e) {
19038                    }
19039                }
19040                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
19041                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19042                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
19043                        | Intent.FLAG_RECEIVER_FOREGROUND);
19044                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
19045                        null, AppOpsManager.OP_NONE, null, false, false,
19046                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19047                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
19048                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
19049                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
19050	            if (initLocale || !mProcessesReady) {
19051                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19052                    }
19053                    broadcastIntentLocked(null, null, intent,
19054                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19055                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19056                }
19057            }
19058            // Update the configuration with WM first and check if any of the stacks need to be
19059            // resized due to the configuration change. If so, resize the stacks now and do any
19060            // relaunches if necessary. This way we don't need to relaunch again below in
19061            // ensureActivityConfigurationLocked().
19062            if (mWindowManager != null) {
19063                final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
19064                if (resizedStacks != null) {
19065                    for (int stackId : resizedStacks) {
19066                        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
19067                        mStackSupervisor.resizeStackLocked(
19068                                stackId, newBounds, null, null, false, false, deferResume);
19069                    }
19070                }
19071            }
19072        }
19073
19074        boolean kept = true;
19075        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
19076        // mainStack is null during startup.
19077        if (mainStack != null) {
19078            if (changes != 0 && starting == null) {
19079                // If the configuration changed, and the caller is not already
19080                // in the process of starting an activity, then find the top
19081                // activity to check if its configuration needs to change.
19082                starting = mainStack.topRunningActivityLocked();
19083            }
19084
19085            if (starting != null) {
19086                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
19087                // And we need to make sure at this point that all other activities
19088                // are made visible with the correct configuration.
19089                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
19090                        !PRESERVE_WINDOWS);
19091            }
19092        }
19093        if (mWindowManager != null) {
19094            mWindowManager.continueSurfaceLayout();
19095        }
19096        return kept;
19097    }
19098
19099    /**
19100     * Decide based on the configuration whether we should shouw the ANR,
19101     * crash, etc dialogs.  The idea is that if there is no affordence to
19102     * press the on-screen buttons, or the user experience would be more
19103     * greatly impacted than the crash itself, we shouldn't show the dialog.
19104     *
19105     * A thought: SystemUI might also want to get told about this, the Power
19106     * dialog / global actions also might want different behaviors.
19107     */
19108    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
19109        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
19110                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
19111                                   && config.navigation == Configuration.NAVIGATION_NONAV);
19112        int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
19113        final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
19114                && !(modeType == Configuration.UI_MODE_TYPE_WATCH && "user".equals(Build.TYPE)));
19115        return inputMethodExists && uiModeSupportsDialogs && !inVrMode;
19116    }
19117
19118    @Override
19119    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
19120        synchronized (this) {
19121            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
19122            if (srec != null) {
19123                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
19124            }
19125        }
19126        return false;
19127    }
19128
19129    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
19130            Intent resultData) {
19131
19132        synchronized (this) {
19133            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
19134            if (r != null) {
19135                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
19136            }
19137            return false;
19138        }
19139    }
19140
19141    public int getLaunchedFromUid(IBinder activityToken) {
19142        ActivityRecord srec;
19143        synchronized (this) {
19144            srec = ActivityRecord.forTokenLocked(activityToken);
19145        }
19146        if (srec == null) {
19147            return -1;
19148        }
19149        return srec.launchedFromUid;
19150    }
19151
19152    public String getLaunchedFromPackage(IBinder activityToken) {
19153        ActivityRecord srec;
19154        synchronized (this) {
19155            srec = ActivityRecord.forTokenLocked(activityToken);
19156        }
19157        if (srec == null) {
19158            return null;
19159        }
19160        return srec.launchedFromPackage;
19161    }
19162
19163    // =========================================================
19164    // LIFETIME MANAGEMENT
19165    // =========================================================
19166
19167    // Returns which broadcast queue the app is the current [or imminent] receiver
19168    // on, or 'null' if the app is not an active broadcast recipient.
19169    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
19170        BroadcastRecord r = app.curReceiver;
19171        if (r != null) {
19172            return r.queue;
19173        }
19174
19175        // It's not the current receiver, but it might be starting up to become one
19176        synchronized (this) {
19177            for (BroadcastQueue queue : mBroadcastQueues) {
19178                r = queue.mPendingBroadcast;
19179                if (r != null && r.curApp == app) {
19180                    // found it; report which queue it's in
19181                    return queue;
19182                }
19183            }
19184        }
19185
19186        return null;
19187    }
19188
19189    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
19190            int targetUid, ComponentName targetComponent, String targetProcess) {
19191        if (!mTrackingAssociations) {
19192            return null;
19193        }
19194        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19195                = mAssociations.get(targetUid);
19196        if (components == null) {
19197            components = new ArrayMap<>();
19198            mAssociations.put(targetUid, components);
19199        }
19200        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19201        if (sourceUids == null) {
19202            sourceUids = new SparseArray<>();
19203            components.put(targetComponent, sourceUids);
19204        }
19205        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19206        if (sourceProcesses == null) {
19207            sourceProcesses = new ArrayMap<>();
19208            sourceUids.put(sourceUid, sourceProcesses);
19209        }
19210        Association ass = sourceProcesses.get(sourceProcess);
19211        if (ass == null) {
19212            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
19213                    targetProcess);
19214            sourceProcesses.put(sourceProcess, ass);
19215        }
19216        ass.mCount++;
19217        ass.mNesting++;
19218        if (ass.mNesting == 1) {
19219            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
19220            ass.mLastState = sourceState;
19221        }
19222        return ass;
19223    }
19224
19225    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
19226            ComponentName targetComponent) {
19227        if (!mTrackingAssociations) {
19228            return;
19229        }
19230        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19231                = mAssociations.get(targetUid);
19232        if (components == null) {
19233            return;
19234        }
19235        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19236        if (sourceUids == null) {
19237            return;
19238        }
19239        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19240        if (sourceProcesses == null) {
19241            return;
19242        }
19243        Association ass = sourceProcesses.get(sourceProcess);
19244        if (ass == null || ass.mNesting <= 0) {
19245            return;
19246        }
19247        ass.mNesting--;
19248        if (ass.mNesting == 0) {
19249            long uptime = SystemClock.uptimeMillis();
19250            ass.mTime += uptime - ass.mStartTime;
19251            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19252                    += uptime - ass.mLastStateUptime;
19253            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
19254        }
19255    }
19256
19257    private void noteUidProcessState(final int uid, final int state) {
19258        mBatteryStatsService.noteUidProcessState(uid, state);
19259        if (mTrackingAssociations) {
19260            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
19261                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
19262                        = mAssociations.valueAt(i1);
19263                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
19264                    SparseArray<ArrayMap<String, Association>> sourceUids
19265                            = targetComponents.valueAt(i2);
19266                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
19267                    if (sourceProcesses != null) {
19268                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
19269                            Association ass = sourceProcesses.valueAt(i4);
19270                            if (ass.mNesting >= 1) {
19271                                // currently associated
19272                                long uptime = SystemClock.uptimeMillis();
19273                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19274                                        += uptime - ass.mLastStateUptime;
19275                                ass.mLastState = state;
19276                                ass.mLastStateUptime = uptime;
19277                            }
19278                        }
19279                    }
19280                }
19281            }
19282        }
19283    }
19284
19285    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
19286            boolean doingAll, long now) {
19287        if (mAdjSeq == app.adjSeq) {
19288            // This adjustment has already been computed.
19289            return app.curRawAdj;
19290        }
19291
19292        if (app.thread == null) {
19293            app.adjSeq = mAdjSeq;
19294            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19295            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19296            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
19297        }
19298
19299        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
19300        app.adjSource = null;
19301        app.adjTarget = null;
19302        app.empty = false;
19303        app.cached = false;
19304
19305        final int activitiesSize = app.activities.size();
19306
19307        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19308            // The max adjustment doesn't allow this app to be anything
19309            // below foreground, so it is not worth doing work for it.
19310            app.adjType = "fixed";
19311            app.adjSeq = mAdjSeq;
19312            app.curRawAdj = app.maxAdj;
19313            app.foregroundActivities = false;
19314            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19315            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
19316            // System processes can do UI, and when they do we want to have
19317            // them trim their memory after the user leaves the UI.  To
19318            // facilitate this, here we need to determine whether or not it
19319            // is currently showing UI.
19320            app.systemNoUi = true;
19321            if (app == TOP_APP) {
19322                app.systemNoUi = false;
19323                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19324                app.adjType = "pers-top-activity";
19325            } else if (app.hasTopUi) {
19326                app.systemNoUi = false;
19327                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19328                app.adjType = "pers-top-ui";
19329            } else if (activitiesSize > 0) {
19330                for (int j = 0; j < activitiesSize; j++) {
19331                    final ActivityRecord r = app.activities.get(j);
19332                    if (r.visible) {
19333                        app.systemNoUi = false;
19334                    }
19335                }
19336            }
19337            if (!app.systemNoUi) {
19338                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
19339            }
19340            return (app.curAdj=app.maxAdj);
19341        }
19342
19343        app.systemNoUi = false;
19344
19345        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
19346
19347        // Determine the importance of the process, starting with most
19348        // important to least, and assign an appropriate OOM adjustment.
19349        int adj;
19350        int schedGroup;
19351        int procState;
19352        boolean foregroundActivities = false;
19353        BroadcastQueue queue;
19354        if (app == TOP_APP) {
19355            // The last app on the list is the foreground app.
19356            adj = ProcessList.FOREGROUND_APP_ADJ;
19357            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19358            app.adjType = "top-activity";
19359            foregroundActivities = true;
19360            procState = PROCESS_STATE_CUR_TOP;
19361        } else if (app.instrumentationClass != null) {
19362            // Don't want to kill running instrumentation.
19363            adj = ProcessList.FOREGROUND_APP_ADJ;
19364            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19365            app.adjType = "instrumentation";
19366            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19367        } else if ((queue = isReceivingBroadcast(app)) != null) {
19368            // An app that is currently receiving a broadcast also
19369            // counts as being in the foreground for OOM killer purposes.
19370            // It's placed in a sched group based on the nature of the
19371            // broadcast as reflected by which queue it's active in.
19372            adj = ProcessList.FOREGROUND_APP_ADJ;
19373            schedGroup = (queue == mFgBroadcastQueue)
19374                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19375            app.adjType = "broadcast";
19376            procState = ActivityManager.PROCESS_STATE_RECEIVER;
19377        } else if (app.executingServices.size() > 0) {
19378            // An app that is currently executing a service callback also
19379            // counts as being in the foreground.
19380            adj = ProcessList.FOREGROUND_APP_ADJ;
19381            schedGroup = app.execServicesFg ?
19382                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19383            app.adjType = "exec-service";
19384            procState = ActivityManager.PROCESS_STATE_SERVICE;
19385            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
19386        } else {
19387            // As far as we know the process is empty.  We may change our mind later.
19388            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19389            // At this point we don't actually know the adjustment.  Use the cached adj
19390            // value that the caller wants us to.
19391            adj = cachedAdj;
19392            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19393            app.cached = true;
19394            app.empty = true;
19395            app.adjType = "cch-empty";
19396        }
19397
19398        // Examine all activities if not already foreground.
19399        if (!foregroundActivities && activitiesSize > 0) {
19400            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
19401            for (int j = 0; j < activitiesSize; j++) {
19402                final ActivityRecord r = app.activities.get(j);
19403                if (r.app != app) {
19404                    Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
19405                            + " instead of expected " + app);
19406                    if (r.app == null || (r.app.uid == app.uid)) {
19407                        // Only fix things up when they look sane
19408                        r.app = app;
19409                    } else {
19410                        continue;
19411                    }
19412                }
19413                if (r.visible) {
19414                    // App has a visible activity; only upgrade adjustment.
19415                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19416                        adj = ProcessList.VISIBLE_APP_ADJ;
19417                        app.adjType = "visible";
19418                    }
19419                    if (procState > PROCESS_STATE_CUR_TOP) {
19420                        procState = PROCESS_STATE_CUR_TOP;
19421                    }
19422                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19423                    app.cached = false;
19424                    app.empty = false;
19425                    foregroundActivities = true;
19426                    if (r.task != null && minLayer > 0) {
19427                        final int layer = r.task.mLayerRank;
19428                        if (layer >= 0 && minLayer > layer) {
19429                            minLayer = layer;
19430                        }
19431                    }
19432                    break;
19433                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
19434                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19435                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19436                        app.adjType = "pausing";
19437                    }
19438                    if (procState > PROCESS_STATE_CUR_TOP) {
19439                        procState = PROCESS_STATE_CUR_TOP;
19440                    }
19441                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19442                    app.cached = false;
19443                    app.empty = false;
19444                    foregroundActivities = true;
19445                } else if (r.state == ActivityState.STOPPING) {
19446                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19447                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19448                        app.adjType = "stopping";
19449                    }
19450                    // For the process state, we will at this point consider the
19451                    // process to be cached.  It will be cached either as an activity
19452                    // or empty depending on whether the activity is finishing.  We do
19453                    // this so that we can treat the process as cached for purposes of
19454                    // memory trimming (determing current memory level, trim command to
19455                    // send to process) since there can be an arbitrary number of stopping
19456                    // processes and they should soon all go into the cached state.
19457                    if (!r.finishing) {
19458                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19459                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19460                        }
19461                    }
19462                    app.cached = false;
19463                    app.empty = false;
19464                    foregroundActivities = true;
19465                } else {
19466                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19467                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19468                        app.adjType = "cch-act";
19469                    }
19470                }
19471            }
19472            if (adj == ProcessList.VISIBLE_APP_ADJ) {
19473                adj += minLayer;
19474            }
19475        }
19476
19477        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
19478                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
19479            if (app.foregroundServices) {
19480                // The user is aware of this app, so make it visible.
19481                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19482                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19483                app.cached = false;
19484                app.adjType = "fg-service";
19485                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19486            } else if (app.forcingToForeground != null) {
19487                // The user is aware of this app, so make it visible.
19488                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19489                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19490                app.cached = false;
19491                app.adjType = "force-fg";
19492                app.adjSource = app.forcingToForeground;
19493                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19494            }
19495        }
19496
19497        if (app == mHeavyWeightProcess) {
19498            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
19499                // We don't want to kill the current heavy-weight process.
19500                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
19501                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19502                app.cached = false;
19503                app.adjType = "heavy";
19504            }
19505            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19506                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
19507            }
19508        }
19509
19510        if (app == mHomeProcess) {
19511            if (adj > ProcessList.HOME_APP_ADJ) {
19512                // This process is hosting what we currently consider to be the
19513                // home app, so we don't want to let it go into the background.
19514                adj = ProcessList.HOME_APP_ADJ;
19515                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19516                app.cached = false;
19517                app.adjType = "home";
19518            }
19519            if (procState > ActivityManager.PROCESS_STATE_HOME) {
19520                procState = ActivityManager.PROCESS_STATE_HOME;
19521            }
19522        }
19523
19524        if (app == mPreviousProcess && app.activities.size() > 0) {
19525            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19526                // This was the previous process that showed UI to the user.
19527                // We want to try to keep it around more aggressively, to give
19528                // a good experience around switching between two apps.
19529                adj = ProcessList.PREVIOUS_APP_ADJ;
19530                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19531                app.cached = false;
19532                app.adjType = "previous";
19533            }
19534            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19535                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19536            }
19537        }
19538
19539        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
19540                + " reason=" + app.adjType);
19541
19542        // By default, we use the computed adjustment.  It may be changed if
19543        // there are applications dependent on our services or providers, but
19544        // this gives us a baseline and makes sure we don't get into an
19545        // infinite recursion.
19546        app.adjSeq = mAdjSeq;
19547        app.curRawAdj = adj;
19548        app.hasStartedServices = false;
19549
19550        if (mBackupTarget != null && app == mBackupTarget.app) {
19551            // If possible we want to avoid killing apps while they're being backed up
19552            if (adj > ProcessList.BACKUP_APP_ADJ) {
19553                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
19554                adj = ProcessList.BACKUP_APP_ADJ;
19555                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19556                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19557                }
19558                app.adjType = "backup";
19559                app.cached = false;
19560            }
19561            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
19562                procState = ActivityManager.PROCESS_STATE_BACKUP;
19563            }
19564        }
19565
19566        boolean mayBeTop = false;
19567
19568        for (int is = app.services.size()-1;
19569                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19570                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19571                        || procState > ActivityManager.PROCESS_STATE_TOP);
19572                is--) {
19573            ServiceRecord s = app.services.valueAt(is);
19574            if (s.startRequested) {
19575                app.hasStartedServices = true;
19576                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
19577                    procState = ActivityManager.PROCESS_STATE_SERVICE;
19578                }
19579                if (app.hasShownUi && app != mHomeProcess) {
19580                    // If this process has shown some UI, let it immediately
19581                    // go to the LRU list because it may be pretty heavy with
19582                    // UI stuff.  We'll tag it with a label just to help
19583                    // debug and understand what is going on.
19584                    if (adj > ProcessList.SERVICE_ADJ) {
19585                        app.adjType = "cch-started-ui-services";
19586                    }
19587                } else {
19588                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19589                        // This service has seen some activity within
19590                        // recent memory, so we will keep its process ahead
19591                        // of the background processes.
19592                        if (adj > ProcessList.SERVICE_ADJ) {
19593                            adj = ProcessList.SERVICE_ADJ;
19594                            app.adjType = "started-services";
19595                            app.cached = false;
19596                        }
19597                    }
19598                    // If we have let the service slide into the background
19599                    // state, still have some text describing what it is doing
19600                    // even though the service no longer has an impact.
19601                    if (adj > ProcessList.SERVICE_ADJ) {
19602                        app.adjType = "cch-started-services";
19603                    }
19604                }
19605            }
19606
19607            for (int conni = s.connections.size()-1;
19608                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19609                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19610                            || procState > ActivityManager.PROCESS_STATE_TOP);
19611                    conni--) {
19612                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
19613                for (int i = 0;
19614                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
19615                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19616                                || procState > ActivityManager.PROCESS_STATE_TOP);
19617                        i++) {
19618                    // XXX should compute this based on the max of
19619                    // all connected clients.
19620                    ConnectionRecord cr = clist.get(i);
19621                    if (cr.binding.client == app) {
19622                        // Binding to ourself is not interesting.
19623                        continue;
19624                    }
19625
19626                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
19627                        ProcessRecord client = cr.binding.client;
19628                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
19629                                TOP_APP, doingAll, now);
19630                        int clientProcState = client.curProcState;
19631                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19632                            // If the other app is cached for any reason, for purposes here
19633                            // we are going to consider it empty.  The specific cached state
19634                            // doesn't propagate except under certain conditions.
19635                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19636                        }
19637                        String adjType = null;
19638                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
19639                            // Not doing bind OOM management, so treat
19640                            // this guy more like a started service.
19641                            if (app.hasShownUi && app != mHomeProcess) {
19642                                // If this process has shown some UI, let it immediately
19643                                // go to the LRU list because it may be pretty heavy with
19644                                // UI stuff.  We'll tag it with a label just to help
19645                                // debug and understand what is going on.
19646                                if (adj > clientAdj) {
19647                                    adjType = "cch-bound-ui-services";
19648                                }
19649                                app.cached = false;
19650                                clientAdj = adj;
19651                                clientProcState = procState;
19652                            } else {
19653                                if (now >= (s.lastActivity
19654                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19655                                    // This service has not seen activity within
19656                                    // recent memory, so allow it to drop to the
19657                                    // LRU list if there is no other reason to keep
19658                                    // it around.  We'll also tag it with a label just
19659                                    // to help debug and undertand what is going on.
19660                                    if (adj > clientAdj) {
19661                                        adjType = "cch-bound-services";
19662                                    }
19663                                    clientAdj = adj;
19664                                }
19665                            }
19666                        }
19667                        if (adj > clientAdj) {
19668                            // If this process has recently shown UI, and
19669                            // the process that is binding to it is less
19670                            // important than being visible, then we don't
19671                            // care about the binding as much as we care
19672                            // about letting this process get into the LRU
19673                            // list to be killed and restarted if needed for
19674                            // memory.
19675                            if (app.hasShownUi && app != mHomeProcess
19676                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19677                                adjType = "cch-bound-ui-services";
19678                            } else {
19679                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
19680                                        |Context.BIND_IMPORTANT)) != 0) {
19681                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
19682                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
19683                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
19684                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
19685                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19686                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19687                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
19688                                    adj = clientAdj;
19689                                } else {
19690                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19691                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
19692                                    }
19693                                }
19694                                if (!client.cached) {
19695                                    app.cached = false;
19696                                }
19697                                adjType = "service";
19698                            }
19699                        }
19700                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19701                            // This will treat important bound services identically to
19702                            // the top app, which may behave differently than generic
19703                            // foreground work.
19704                            if (client.curSchedGroup > schedGroup) {
19705                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19706                                    schedGroup = client.curSchedGroup;
19707                                } else {
19708                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19709                                }
19710                            }
19711                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19712                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19713                                    // Special handling of clients who are in the top state.
19714                                    // We *may* want to consider this process to be in the
19715                                    // top state as well, but only if there is not another
19716                                    // reason for it to be running.  Being on the top is a
19717                                    // special state, meaning you are specifically running
19718                                    // for the current top app.  If the process is already
19719                                    // running in the background for some other reason, it
19720                                    // is more important to continue considering it to be
19721                                    // in the background state.
19722                                    mayBeTop = true;
19723                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19724                                } else {
19725                                    // Special handling for above-top states (persistent
19726                                    // processes).  These should not bring the current process
19727                                    // into the top state, since they are not on top.  Instead
19728                                    // give them the best state after that.
19729                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
19730                                        clientProcState =
19731                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19732                                    } else if (mWakefulness
19733                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
19734                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
19735                                                    != 0) {
19736                                        clientProcState =
19737                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19738                                    } else {
19739                                        clientProcState =
19740                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19741                                    }
19742                                }
19743                            }
19744                        } else {
19745                            if (clientProcState <
19746                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19747                                clientProcState =
19748                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19749                            }
19750                        }
19751                        if (procState > clientProcState) {
19752                            procState = clientProcState;
19753                        }
19754                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19755                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
19756                            app.pendingUiClean = true;
19757                        }
19758                        if (adjType != null) {
19759                            app.adjType = adjType;
19760                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19761                                    .REASON_SERVICE_IN_USE;
19762                            app.adjSource = cr.binding.client;
19763                            app.adjSourceProcState = clientProcState;
19764                            app.adjTarget = s.name;
19765                        }
19766                    }
19767                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
19768                        app.treatLikeActivity = true;
19769                    }
19770                    final ActivityRecord a = cr.activity;
19771                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
19772                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19773                            (a.visible || a.state == ActivityState.RESUMED ||
19774                             a.state == ActivityState.PAUSING)) {
19775                            adj = ProcessList.FOREGROUND_APP_ADJ;
19776                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19777                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19778                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
19779                                } else {
19780                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19781                                }
19782                            }
19783                            app.cached = false;
19784                            app.adjType = "service";
19785                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19786                                    .REASON_SERVICE_IN_USE;
19787                            app.adjSource = a;
19788                            app.adjSourceProcState = procState;
19789                            app.adjTarget = s.name;
19790                        }
19791                    }
19792                }
19793            }
19794        }
19795
19796        for (int provi = app.pubProviders.size()-1;
19797                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19798                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19799                        || procState > ActivityManager.PROCESS_STATE_TOP);
19800                provi--) {
19801            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19802            for (int i = cpr.connections.size()-1;
19803                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19804                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19805                            || procState > ActivityManager.PROCESS_STATE_TOP);
19806                    i--) {
19807                ContentProviderConnection conn = cpr.connections.get(i);
19808                ProcessRecord client = conn.client;
19809                if (client == app) {
19810                    // Being our own client is not interesting.
19811                    continue;
19812                }
19813                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19814                int clientProcState = client.curProcState;
19815                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19816                    // If the other app is cached for any reason, for purposes here
19817                    // we are going to consider it empty.
19818                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19819                }
19820                if (adj > clientAdj) {
19821                    if (app.hasShownUi && app != mHomeProcess
19822                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19823                        app.adjType = "cch-ui-provider";
19824                    } else {
19825                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19826                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19827                        app.adjType = "provider";
19828                    }
19829                    app.cached &= client.cached;
19830                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19831                            .REASON_PROVIDER_IN_USE;
19832                    app.adjSource = client;
19833                    app.adjSourceProcState = clientProcState;
19834                    app.adjTarget = cpr.name;
19835                }
19836                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19837                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19838                        // Special handling of clients who are in the top state.
19839                        // We *may* want to consider this process to be in the
19840                        // top state as well, but only if there is not another
19841                        // reason for it to be running.  Being on the top is a
19842                        // special state, meaning you are specifically running
19843                        // for the current top app.  If the process is already
19844                        // running in the background for some other reason, it
19845                        // is more important to continue considering it to be
19846                        // in the background state.
19847                        mayBeTop = true;
19848                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19849                    } else {
19850                        // Special handling for above-top states (persistent
19851                        // processes).  These should not bring the current process
19852                        // into the top state, since they are not on top.  Instead
19853                        // give them the best state after that.
19854                        clientProcState =
19855                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19856                    }
19857                }
19858                if (procState > clientProcState) {
19859                    procState = clientProcState;
19860                }
19861                if (client.curSchedGroup > schedGroup) {
19862                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19863                }
19864            }
19865            // If the provider has external (non-framework) process
19866            // dependencies, ensure that its adjustment is at least
19867            // FOREGROUND_APP_ADJ.
19868            if (cpr.hasExternalProcessHandles()) {
19869                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19870                    adj = ProcessList.FOREGROUND_APP_ADJ;
19871                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19872                    app.cached = false;
19873                    app.adjType = "provider";
19874                    app.adjTarget = cpr.name;
19875                }
19876                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19877                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19878                }
19879            }
19880        }
19881
19882        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19883            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19884                adj = ProcessList.PREVIOUS_APP_ADJ;
19885                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19886                app.cached = false;
19887                app.adjType = "provider";
19888            }
19889            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19890                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19891            }
19892        }
19893
19894        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19895            // A client of one of our services or providers is in the top state.  We
19896            // *may* want to be in the top state, but not if we are already running in
19897            // the background for some other reason.  For the decision here, we are going
19898            // to pick out a few specific states that we want to remain in when a client
19899            // is top (states that tend to be longer-term) and otherwise allow it to go
19900            // to the top state.
19901            switch (procState) {
19902                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19903                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19904                case ActivityManager.PROCESS_STATE_SERVICE:
19905                    // These all are longer-term states, so pull them up to the top
19906                    // of the background states, but not all the way to the top state.
19907                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19908                    break;
19909                default:
19910                    // Otherwise, top is a better choice, so take it.
19911                    procState = ActivityManager.PROCESS_STATE_TOP;
19912                    break;
19913            }
19914        }
19915
19916        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19917            if (app.hasClientActivities) {
19918                // This is a cached process, but with client activities.  Mark it so.
19919                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19920                app.adjType = "cch-client-act";
19921            } else if (app.treatLikeActivity) {
19922                // This is a cached process, but somebody wants us to treat it like it has
19923                // an activity, okay!
19924                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19925                app.adjType = "cch-as-act";
19926            }
19927        }
19928
19929        if (adj == ProcessList.SERVICE_ADJ) {
19930            if (doingAll) {
19931                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19932                mNewNumServiceProcs++;
19933                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19934                if (!app.serviceb) {
19935                    // This service isn't far enough down on the LRU list to
19936                    // normally be a B service, but if we are low on RAM and it
19937                    // is large we want to force it down since we would prefer to
19938                    // keep launcher over it.
19939                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19940                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19941                        app.serviceHighRam = true;
19942                        app.serviceb = true;
19943                        //Slog.i(TAG, "ADJ " + app + " high ram!");
19944                    } else {
19945                        mNewNumAServiceProcs++;
19946                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
19947                    }
19948                } else {
19949                    app.serviceHighRam = false;
19950                }
19951            }
19952            if (app.serviceb) {
19953                adj = ProcessList.SERVICE_B_ADJ;
19954            }
19955        }
19956
19957        app.curRawAdj = adj;
19958
19959        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19960        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19961        if (adj > app.maxAdj) {
19962            adj = app.maxAdj;
19963            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19964                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19965            }
19966        }
19967
19968        // Do final modification to adj.  Everything we do between here and applying
19969        // the final setAdj must be done in this function, because we will also use
19970        // it when computing the final cached adj later.  Note that we don't need to
19971        // worry about this for max adj above, since max adj will always be used to
19972        // keep it out of the cached vaues.
19973        app.curAdj = app.modifyRawOomAdj(adj);
19974        app.curSchedGroup = schedGroup;
19975        app.curProcState = procState;
19976        app.foregroundActivities = foregroundActivities;
19977
19978        return app.curRawAdj;
19979    }
19980
19981    /**
19982     * Record new PSS sample for a process.
19983     */
19984    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19985            long now) {
19986        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19987                swapPss * 1024);
19988        proc.lastPssTime = now;
19989        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19990        if (DEBUG_PSS) Slog.d(TAG_PSS,
19991                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19992                + " state=" + ProcessList.makeProcStateString(procState));
19993        if (proc.initialIdlePss == 0) {
19994            proc.initialIdlePss = pss;
19995        }
19996        proc.lastPss = pss;
19997        proc.lastSwapPss = swapPss;
19998        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19999            proc.lastCachedPss = pss;
20000            proc.lastCachedSwapPss = swapPss;
20001        }
20002
20003        final SparseArray<Pair<Long, String>> watchUids
20004                = mMemWatchProcesses.getMap().get(proc.processName);
20005        Long check = null;
20006        if (watchUids != null) {
20007            Pair<Long, String> val = watchUids.get(proc.uid);
20008            if (val == null) {
20009                val = watchUids.get(0);
20010            }
20011            if (val != null) {
20012                check = val.first;
20013            }
20014        }
20015        if (check != null) {
20016            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
20017                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20018                if (!isDebuggable) {
20019                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
20020                        isDebuggable = true;
20021                    }
20022                }
20023                if (isDebuggable) {
20024                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
20025                    final ProcessRecord myProc = proc;
20026                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
20027                    mMemWatchDumpProcName = proc.processName;
20028                    mMemWatchDumpFile = heapdumpFile.toString();
20029                    mMemWatchDumpPid = proc.pid;
20030                    mMemWatchDumpUid = proc.uid;
20031                    BackgroundThread.getHandler().post(new Runnable() {
20032                        @Override
20033                        public void run() {
20034                            revokeUriPermission(ActivityThread.currentActivityThread()
20035                                            .getApplicationThread(),
20036                                    DumpHeapActivity.JAVA_URI,
20037                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
20038                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
20039                                    UserHandle.myUserId());
20040                            ParcelFileDescriptor fd = null;
20041                            try {
20042                                heapdumpFile.delete();
20043                                fd = ParcelFileDescriptor.open(heapdumpFile,
20044                                        ParcelFileDescriptor.MODE_CREATE |
20045                                                ParcelFileDescriptor.MODE_TRUNCATE |
20046                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
20047                                                ParcelFileDescriptor.MODE_APPEND);
20048                                IApplicationThread thread = myProc.thread;
20049                                if (thread != null) {
20050                                    try {
20051                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
20052                                                "Requesting dump heap from "
20053                                                + myProc + " to " + heapdumpFile);
20054                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
20055                                    } catch (RemoteException e) {
20056                                    }
20057                                }
20058                            } catch (FileNotFoundException e) {
20059                                e.printStackTrace();
20060                            } finally {
20061                                if (fd != null) {
20062                                    try {
20063                                        fd.close();
20064                                    } catch (IOException e) {
20065                                    }
20066                                }
20067                            }
20068                        }
20069                    });
20070                } else {
20071                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
20072                            + ", but debugging not enabled");
20073                }
20074            }
20075        }
20076    }
20077
20078    /**
20079     * Schedule PSS collection of a process.
20080     */
20081    void requestPssLocked(ProcessRecord proc, int procState) {
20082        if (mPendingPssProcesses.contains(proc)) {
20083            return;
20084        }
20085        if (mPendingPssProcesses.size() == 0) {
20086            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
20087        }
20088        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
20089        proc.pssProcState = procState;
20090        mPendingPssProcesses.add(proc);
20091    }
20092
20093    /**
20094     * Schedule PSS collection of all processes.
20095     */
20096    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
20097        if (!always) {
20098            if (now < (mLastFullPssTime +
20099                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
20100                return;
20101            }
20102        }
20103        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
20104        mLastFullPssTime = now;
20105        mFullPssPending = true;
20106        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
20107        mPendingPssProcesses.clear();
20108        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20109            ProcessRecord app = mLruProcesses.get(i);
20110            if (app.thread == null
20111                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
20112                continue;
20113            }
20114            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
20115                app.pssProcState = app.setProcState;
20116                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20117                        mTestPssMode, isSleepingLocked(), now);
20118                mPendingPssProcesses.add(app);
20119            }
20120        }
20121        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
20122    }
20123
20124    public void setTestPssMode(boolean enabled) {
20125        synchronized (this) {
20126            mTestPssMode = enabled;
20127            if (enabled) {
20128                // Whenever we enable the mode, we want to take a snapshot all of current
20129                // process mem use.
20130                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
20131            }
20132        }
20133    }
20134
20135    /**
20136     * Ask a given process to GC right now.
20137     */
20138    final void performAppGcLocked(ProcessRecord app) {
20139        try {
20140            app.lastRequestedGc = SystemClock.uptimeMillis();
20141            if (app.thread != null) {
20142                if (app.reportLowMemory) {
20143                    app.reportLowMemory = false;
20144                    app.thread.scheduleLowMemory();
20145                } else {
20146                    app.thread.processInBackground();
20147                }
20148            }
20149        } catch (Exception e) {
20150            // whatever.
20151        }
20152    }
20153
20154    /**
20155     * Returns true if things are idle enough to perform GCs.
20156     */
20157    private final boolean canGcNowLocked() {
20158        boolean processingBroadcasts = false;
20159        for (BroadcastQueue q : mBroadcastQueues) {
20160            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
20161                processingBroadcasts = true;
20162            }
20163        }
20164        return !processingBroadcasts
20165                && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
20166    }
20167
20168    /**
20169     * Perform GCs on all processes that are waiting for it, but only
20170     * if things are idle.
20171     */
20172    final void performAppGcsLocked() {
20173        final int N = mProcessesToGc.size();
20174        if (N <= 0) {
20175            return;
20176        }
20177        if (canGcNowLocked()) {
20178            while (mProcessesToGc.size() > 0) {
20179                ProcessRecord proc = mProcessesToGc.remove(0);
20180                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
20181                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
20182                            <= SystemClock.uptimeMillis()) {
20183                        // To avoid spamming the system, we will GC processes one
20184                        // at a time, waiting a few seconds between each.
20185                        performAppGcLocked(proc);
20186                        scheduleAppGcsLocked();
20187                        return;
20188                    } else {
20189                        // It hasn't been long enough since we last GCed this
20190                        // process...  put it in the list to wait for its time.
20191                        addProcessToGcListLocked(proc);
20192                        break;
20193                    }
20194                }
20195            }
20196
20197            scheduleAppGcsLocked();
20198        }
20199    }
20200
20201    /**
20202     * If all looks good, perform GCs on all processes waiting for them.
20203     */
20204    final void performAppGcsIfAppropriateLocked() {
20205        if (canGcNowLocked()) {
20206            performAppGcsLocked();
20207            return;
20208        }
20209        // Still not idle, wait some more.
20210        scheduleAppGcsLocked();
20211    }
20212
20213    /**
20214     * Schedule the execution of all pending app GCs.
20215     */
20216    final void scheduleAppGcsLocked() {
20217        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
20218
20219        if (mProcessesToGc.size() > 0) {
20220            // Schedule a GC for the time to the next process.
20221            ProcessRecord proc = mProcessesToGc.get(0);
20222            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
20223
20224            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
20225            long now = SystemClock.uptimeMillis();
20226            if (when < (now+GC_TIMEOUT)) {
20227                when = now + GC_TIMEOUT;
20228            }
20229            mHandler.sendMessageAtTime(msg, when);
20230        }
20231    }
20232
20233    /**
20234     * Add a process to the array of processes waiting to be GCed.  Keeps the
20235     * list in sorted order by the last GC time.  The process can't already be
20236     * on the list.
20237     */
20238    final void addProcessToGcListLocked(ProcessRecord proc) {
20239        boolean added = false;
20240        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
20241            if (mProcessesToGc.get(i).lastRequestedGc <
20242                    proc.lastRequestedGc) {
20243                added = true;
20244                mProcessesToGc.add(i+1, proc);
20245                break;
20246            }
20247        }
20248        if (!added) {
20249            mProcessesToGc.add(0, proc);
20250        }
20251    }
20252
20253    /**
20254     * Set up to ask a process to GC itself.  This will either do it
20255     * immediately, or put it on the list of processes to gc the next
20256     * time things are idle.
20257     */
20258    final void scheduleAppGcLocked(ProcessRecord app) {
20259        long now = SystemClock.uptimeMillis();
20260        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
20261            return;
20262        }
20263        if (!mProcessesToGc.contains(app)) {
20264            addProcessToGcListLocked(app);
20265            scheduleAppGcsLocked();
20266        }
20267    }
20268
20269    final void checkExcessivePowerUsageLocked(boolean doKills) {
20270        updateCpuStatsNow();
20271
20272        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20273        boolean doWakeKills = doKills;
20274        boolean doCpuKills = doKills;
20275        if (mLastPowerCheckRealtime == 0) {
20276            doWakeKills = false;
20277        }
20278        if (mLastPowerCheckUptime == 0) {
20279            doCpuKills = false;
20280        }
20281        if (stats.isScreenOn()) {
20282            doWakeKills = false;
20283        }
20284        final long curRealtime = SystemClock.elapsedRealtime();
20285        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
20286        final long curUptime = SystemClock.uptimeMillis();
20287        final long uptimeSince = curUptime - mLastPowerCheckUptime;
20288        mLastPowerCheckRealtime = curRealtime;
20289        mLastPowerCheckUptime = curUptime;
20290        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
20291            doWakeKills = false;
20292        }
20293        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
20294            doCpuKills = false;
20295        }
20296        int i = mLruProcesses.size();
20297        while (i > 0) {
20298            i--;
20299            ProcessRecord app = mLruProcesses.get(i);
20300            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20301                long wtime;
20302                synchronized (stats) {
20303                    wtime = stats.getProcessWakeTime(app.info.uid,
20304                            app.pid, curRealtime);
20305                }
20306                long wtimeUsed = wtime - app.lastWakeTime;
20307                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
20308                if (DEBUG_POWER) {
20309                    StringBuilder sb = new StringBuilder(128);
20310                    sb.append("Wake for ");
20311                    app.toShortString(sb);
20312                    sb.append(": over ");
20313                    TimeUtils.formatDuration(realtimeSince, sb);
20314                    sb.append(" used ");
20315                    TimeUtils.formatDuration(wtimeUsed, sb);
20316                    sb.append(" (");
20317                    sb.append((wtimeUsed*100)/realtimeSince);
20318                    sb.append("%)");
20319                    Slog.i(TAG_POWER, sb.toString());
20320                    sb.setLength(0);
20321                    sb.append("CPU for ");
20322                    app.toShortString(sb);
20323                    sb.append(": over ");
20324                    TimeUtils.formatDuration(uptimeSince, sb);
20325                    sb.append(" used ");
20326                    TimeUtils.formatDuration(cputimeUsed, sb);
20327                    sb.append(" (");
20328                    sb.append((cputimeUsed*100)/uptimeSince);
20329                    sb.append("%)");
20330                    Slog.i(TAG_POWER, sb.toString());
20331                }
20332                // If a process has held a wake lock for more
20333                // than 50% of the time during this period,
20334                // that sounds bad.  Kill!
20335                if (doWakeKills && realtimeSince > 0
20336                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
20337                    synchronized (stats) {
20338                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
20339                                realtimeSince, wtimeUsed);
20340                    }
20341                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
20342                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
20343                } else if (doCpuKills && uptimeSince > 0
20344                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
20345                    synchronized (stats) {
20346                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
20347                                uptimeSince, cputimeUsed);
20348                    }
20349                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
20350                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
20351                } else {
20352                    app.lastWakeTime = wtime;
20353                    app.lastCpuTime = app.curCpuTime;
20354                }
20355            }
20356        }
20357    }
20358
20359    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
20360            long nowElapsed) {
20361        boolean success = true;
20362
20363        if (app.curRawAdj != app.setRawAdj) {
20364            app.setRawAdj = app.curRawAdj;
20365        }
20366
20367        int changes = 0;
20368
20369        if (app.curAdj != app.setAdj) {
20370            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
20371            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20372                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
20373                    + app.adjType);
20374            app.setAdj = app.curAdj;
20375            app.verifiedAdj = ProcessList.INVALID_ADJ;
20376        }
20377
20378        if (app.setSchedGroup != app.curSchedGroup) {
20379            int oldSchedGroup = app.setSchedGroup;
20380            app.setSchedGroup = app.curSchedGroup;
20381            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20382                    "Setting sched group of " + app.processName
20383                    + " to " + app.curSchedGroup);
20384            if (app.waitingToKill != null && app.curReceiver == null
20385                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
20386                app.kill(app.waitingToKill, true);
20387                success = false;
20388            } else {
20389                int processGroup;
20390                switch (app.curSchedGroup) {
20391                    case ProcessList.SCHED_GROUP_BACKGROUND:
20392                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
20393                        break;
20394                    case ProcessList.SCHED_GROUP_TOP_APP:
20395                    case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
20396                        processGroup = Process.THREAD_GROUP_TOP_APP;
20397                        break;
20398                    default:
20399                        processGroup = Process.THREAD_GROUP_DEFAULT;
20400                        break;
20401                }
20402                long oldId = Binder.clearCallingIdentity();
20403                try {
20404                    Process.setProcessGroup(app.pid, processGroup);
20405                    if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
20406                        // do nothing if we already switched to RT
20407                        if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
20408                            // Switch VR thread for app to SCHED_FIFO
20409                            if (mInVrMode && app.vrThreadTid != 0) {
20410                                try {
20411                                    Process.setThreadScheduler(app.vrThreadTid,
20412                                        Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20413                                } catch (IllegalArgumentException e) {
20414                                    // thread died, ignore
20415                                }
20416                            }
20417                            if (mUseFifoUiScheduling) {
20418                                // Switch UI pipeline for app to SCHED_FIFO
20419                                app.savedPriority = Process.getThreadPriority(app.pid);
20420                                try {
20421                                    Process.setThreadScheduler(app.pid,
20422                                        Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20423                                } catch (IllegalArgumentException e) {
20424                                    // thread died, ignore
20425                                }
20426                                if (app.renderThreadTid != 0) {
20427                                    try {
20428                                        Process.setThreadScheduler(app.renderThreadTid,
20429                                            Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20430                                    } catch (IllegalArgumentException e) {
20431                                        // thread died, ignore
20432                                    }
20433                                    if (DEBUG_OOM_ADJ) {
20434                                        Slog.d("UI_FIFO", "Set RenderThread (TID " +
20435                                            app.renderThreadTid + ") to FIFO");
20436                                    }
20437                                } else {
20438                                    if (DEBUG_OOM_ADJ) {
20439                                        Slog.d("UI_FIFO", "Not setting RenderThread TID");
20440                                    }
20441                                }
20442                            } else {
20443                                // Boost priority for top app UI and render threads
20444                                Process.setThreadPriority(app.pid, -10);
20445                                if (app.renderThreadTid != 0) {
20446                                    try {
20447                                        Process.setThreadPriority(app.renderThreadTid, -10);
20448                                    } catch (IllegalArgumentException e) {
20449                                        // thread died, ignore
20450                                    }
20451                                }
20452                            }
20453                        }
20454                    } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
20455                               app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
20456                        // Reset VR thread to SCHED_OTHER
20457                        // Safe to do even if we're not in VR mode
20458                        if (app.vrThreadTid != 0) {
20459                            Process.setThreadScheduler(app.vrThreadTid, Process.SCHED_OTHER, 0);
20460                        }
20461                        if (mUseFifoUiScheduling) {
20462                            // Reset UI pipeline to SCHED_OTHER
20463                            Process.setThreadScheduler(app.pid, Process.SCHED_OTHER, 0);
20464                            Process.setThreadPriority(app.pid, app.savedPriority);
20465                            if (app.renderThreadTid != 0) {
20466                                Process.setThreadScheduler(app.renderThreadTid,
20467                                    Process.SCHED_OTHER, 0);
20468                                Process.setThreadPriority(app.renderThreadTid, -4);
20469                            }
20470                        } else {
20471                            // Reset priority for top app UI and render threads
20472                            Process.setThreadPriority(app.pid, 0);
20473                            if (app.renderThreadTid != 0) {
20474                                Process.setThreadPriority(app.renderThreadTid, 0);
20475                            }
20476                        }
20477                    }
20478                } catch (Exception e) {
20479                    Slog.w(TAG, "Failed setting process group of " + app.pid
20480                            + " to " + app.curSchedGroup);
20481                    e.printStackTrace();
20482                } finally {
20483                    Binder.restoreCallingIdentity(oldId);
20484                }
20485            }
20486        }
20487        if (app.repForegroundActivities != app.foregroundActivities) {
20488            app.repForegroundActivities = app.foregroundActivities;
20489            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
20490        }
20491        if (app.repProcState != app.curProcState) {
20492            app.repProcState = app.curProcState;
20493            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
20494            if (app.thread != null) {
20495                try {
20496                    if (false) {
20497                        //RuntimeException h = new RuntimeException("here");
20498                        Slog.i(TAG, "Sending new process state " + app.repProcState
20499                                + " to " + app /*, h*/);
20500                    }
20501                    app.thread.setProcessState(app.repProcState);
20502                } catch (RemoteException e) {
20503                }
20504            }
20505        }
20506        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
20507                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
20508            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
20509                // Experimental code to more aggressively collect pss while
20510                // running test...  the problem is that this tends to collect
20511                // the data right when a process is transitioning between process
20512                // states, which well tend to give noisy data.
20513                long start = SystemClock.uptimeMillis();
20514                long pss = Debug.getPss(app.pid, mTmpLong, null);
20515                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
20516                mPendingPssProcesses.remove(app);
20517                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
20518                        + " to " + app.curProcState + ": "
20519                        + (SystemClock.uptimeMillis()-start) + "ms");
20520            }
20521            app.lastStateTime = now;
20522            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20523                    mTestPssMode, isSleepingLocked(), now);
20524            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
20525                    + ProcessList.makeProcStateString(app.setProcState) + " to "
20526                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
20527                    + (app.nextPssTime-now) + ": " + app);
20528        } else {
20529            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
20530                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
20531                    mTestPssMode)))) {
20532                requestPssLocked(app, app.setProcState);
20533                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
20534                        mTestPssMode, isSleepingLocked(), now);
20535            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
20536                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
20537        }
20538        if (app.setProcState != app.curProcState) {
20539            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20540                    "Proc state change of " + app.processName
20541                            + " to " + app.curProcState);
20542            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
20543            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
20544            if (setImportant && !curImportant) {
20545                // This app is no longer something we consider important enough to allow to
20546                // use arbitrary amounts of battery power.  Note
20547                // its current wake lock time to later know to kill it if
20548                // it is not behaving well.
20549                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20550                synchronized (stats) {
20551                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
20552                            app.pid, nowElapsed);
20553                }
20554                app.lastCpuTime = app.curCpuTime;
20555
20556            }
20557            // Inform UsageStats of important process state change
20558            // Must be called before updating setProcState
20559            maybeUpdateUsageStatsLocked(app, nowElapsed);
20560
20561            app.setProcState = app.curProcState;
20562            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20563                app.notCachedSinceIdle = false;
20564            }
20565            if (!doingAll) {
20566                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
20567            } else {
20568                app.procStateChanged = true;
20569            }
20570        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
20571                > USAGE_STATS_INTERACTION_INTERVAL) {
20572            // For apps that sit around for a long time in the interactive state, we need
20573            // to report this at least once a day so they don't go idle.
20574            maybeUpdateUsageStatsLocked(app, nowElapsed);
20575        }
20576
20577        if (changes != 0) {
20578            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20579                    "Changes in " + app + ": " + changes);
20580            int i = mPendingProcessChanges.size()-1;
20581            ProcessChangeItem item = null;
20582            while (i >= 0) {
20583                item = mPendingProcessChanges.get(i);
20584                if (item.pid == app.pid) {
20585                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20586                            "Re-using existing item: " + item);
20587                    break;
20588                }
20589                i--;
20590            }
20591            if (i < 0) {
20592                // No existing item in pending changes; need a new one.
20593                final int NA = mAvailProcessChanges.size();
20594                if (NA > 0) {
20595                    item = mAvailProcessChanges.remove(NA-1);
20596                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20597                            "Retrieving available item: " + item);
20598                } else {
20599                    item = new ProcessChangeItem();
20600                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20601                            "Allocating new item: " + item);
20602                }
20603                item.changes = 0;
20604                item.pid = app.pid;
20605                item.uid = app.info.uid;
20606                if (mPendingProcessChanges.size() == 0) {
20607                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20608                            "*** Enqueueing dispatch processes changed!");
20609                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
20610                }
20611                mPendingProcessChanges.add(item);
20612            }
20613            item.changes |= changes;
20614            item.processState = app.repProcState;
20615            item.foregroundActivities = app.repForegroundActivities;
20616            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20617                    "Item " + Integer.toHexString(System.identityHashCode(item))
20618                    + " " + app.toShortString() + ": changes=" + item.changes
20619                    + " procState=" + item.processState
20620                    + " foreground=" + item.foregroundActivities
20621                    + " type=" + app.adjType + " source=" + app.adjSource
20622                    + " target=" + app.adjTarget);
20623        }
20624
20625        return success;
20626    }
20627
20628    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
20629        final UidRecord.ChangeItem pendingChange;
20630        if (uidRec == null || uidRec.pendingChange == null) {
20631            if (mPendingUidChanges.size() == 0) {
20632                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20633                        "*** Enqueueing dispatch uid changed!");
20634                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
20635            }
20636            final int NA = mAvailUidChanges.size();
20637            if (NA > 0) {
20638                pendingChange = mAvailUidChanges.remove(NA-1);
20639                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20640                        "Retrieving available item: " + pendingChange);
20641            } else {
20642                pendingChange = new UidRecord.ChangeItem();
20643                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20644                        "Allocating new item: " + pendingChange);
20645            }
20646            if (uidRec != null) {
20647                uidRec.pendingChange = pendingChange;
20648                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
20649                    // If this uid is going away, and we haven't yet reported it is gone,
20650                    // then do so now.
20651                    change = UidRecord.CHANGE_GONE_IDLE;
20652                }
20653            } else if (uid < 0) {
20654                throw new IllegalArgumentException("No UidRecord or uid");
20655            }
20656            pendingChange.uidRecord = uidRec;
20657            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
20658            mPendingUidChanges.add(pendingChange);
20659        } else {
20660            pendingChange = uidRec.pendingChange;
20661            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
20662                change = UidRecord.CHANGE_GONE_IDLE;
20663            }
20664        }
20665        pendingChange.change = change;
20666        pendingChange.processState = uidRec != null
20667                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
20668    }
20669
20670    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
20671            String authority) {
20672        if (app == null) return;
20673        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20674            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
20675            if (userState == null) return;
20676            final long now = SystemClock.elapsedRealtime();
20677            Long lastReported = userState.mProviderLastReportedFg.get(authority);
20678            if (lastReported == null || lastReported < now - 60 * 1000L) {
20679                if (mSystemReady) {
20680                    // Cannot touch the user stats if not system ready
20681                    mUsageStatsService.reportContentProviderUsage(
20682                            authority, providerPkgName, app.userId);
20683                }
20684                userState.mProviderLastReportedFg.put(authority, now);
20685            }
20686        }
20687    }
20688
20689    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
20690        if (DEBUG_USAGE_STATS) {
20691            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
20692                    + "] state changes: old = " + app.setProcState + ", new = "
20693                    + app.curProcState);
20694        }
20695        if (mUsageStatsService == null) {
20696            return;
20697        }
20698        boolean isInteraction;
20699        // To avoid some abuse patterns, we are going to be careful about what we consider
20700        // to be an app interaction.  Being the top activity doesn't count while the display
20701        // is sleeping, nor do short foreground services.
20702        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
20703            isInteraction = true;
20704            app.fgInteractionTime = 0;
20705        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
20706            if (app.fgInteractionTime == 0) {
20707                app.fgInteractionTime = nowElapsed;
20708                isInteraction = false;
20709            } else {
20710                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
20711            }
20712        } else {
20713            // If the app was being forced to the foreground, by say a Toast, then
20714            // no need to treat it as an interaction
20715            isInteraction = app.forcingToForeground == null
20716                    && app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20717            app.fgInteractionTime = 0;
20718        }
20719        if (isInteraction && (!app.reportedInteraction
20720                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
20721            app.interactionEventTime = nowElapsed;
20722            String[] packages = app.getPackageList();
20723            if (packages != null) {
20724                for (int i = 0; i < packages.length; i++) {
20725                    mUsageStatsService.reportEvent(packages[i], app.userId,
20726                            UsageEvents.Event.SYSTEM_INTERACTION);
20727                }
20728            }
20729        }
20730        app.reportedInteraction = isInteraction;
20731        if (!isInteraction) {
20732            app.interactionEventTime = 0;
20733        }
20734    }
20735
20736    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
20737        if (proc.thread != null) {
20738            if (proc.baseProcessTracker != null) {
20739                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
20740            }
20741        }
20742    }
20743
20744    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
20745            ProcessRecord TOP_APP, boolean doingAll, long now) {
20746        if (app.thread == null) {
20747            return false;
20748        }
20749
20750        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
20751
20752        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
20753    }
20754
20755    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
20756            boolean oomAdj) {
20757        if (isForeground != proc.foregroundServices) {
20758            proc.foregroundServices = isForeground;
20759            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
20760                    proc.info.uid);
20761            if (isForeground) {
20762                if (curProcs == null) {
20763                    curProcs = new ArrayList<ProcessRecord>();
20764                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
20765                }
20766                if (!curProcs.contains(proc)) {
20767                    curProcs.add(proc);
20768                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
20769                            proc.info.packageName, proc.info.uid);
20770                }
20771            } else {
20772                if (curProcs != null) {
20773                    if (curProcs.remove(proc)) {
20774                        mBatteryStatsService.noteEvent(
20775                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
20776                                proc.info.packageName, proc.info.uid);
20777                        if (curProcs.size() <= 0) {
20778                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
20779                        }
20780                    }
20781                }
20782            }
20783            if (oomAdj) {
20784                updateOomAdjLocked();
20785            }
20786        }
20787    }
20788
20789    private final ActivityRecord resumedAppLocked() {
20790        ActivityRecord act = mStackSupervisor.resumedAppLocked();
20791        String pkg;
20792        int uid;
20793        if (act != null) {
20794            pkg = act.packageName;
20795            uid = act.info.applicationInfo.uid;
20796        } else {
20797            pkg = null;
20798            uid = -1;
20799        }
20800        // Has the UID or resumed package name changed?
20801        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
20802                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
20803            if (mCurResumedPackage != null) {
20804                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
20805                        mCurResumedPackage, mCurResumedUid);
20806            }
20807            mCurResumedPackage = pkg;
20808            mCurResumedUid = uid;
20809            if (mCurResumedPackage != null) {
20810                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
20811                        mCurResumedPackage, mCurResumedUid);
20812            }
20813        }
20814        return act;
20815    }
20816
20817    final boolean updateOomAdjLocked(ProcessRecord app) {
20818        final ActivityRecord TOP_ACT = resumedAppLocked();
20819        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20820        final boolean wasCached = app.cached;
20821
20822        mAdjSeq++;
20823
20824        // This is the desired cached adjusment we want to tell it to use.
20825        // If our app is currently cached, we know it, and that is it.  Otherwise,
20826        // we don't know it yet, and it needs to now be cached we will then
20827        // need to do a complete oom adj.
20828        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
20829                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
20830        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
20831                SystemClock.uptimeMillis());
20832        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
20833            // Changed to/from cached state, so apps after it in the LRU
20834            // list may also be changed.
20835            updateOomAdjLocked();
20836        }
20837        return success;
20838    }
20839
20840    final void updateOomAdjLocked() {
20841        final ActivityRecord TOP_ACT = resumedAppLocked();
20842        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20843        final long now = SystemClock.uptimeMillis();
20844        final long nowElapsed = SystemClock.elapsedRealtime();
20845        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20846        final int N = mLruProcesses.size();
20847
20848        if (false) {
20849            RuntimeException e = new RuntimeException();
20850            e.fillInStackTrace();
20851            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20852        }
20853
20854        // Reset state in all uid records.
20855        for (int i=mActiveUids.size()-1; i>=0; i--) {
20856            final UidRecord uidRec = mActiveUids.valueAt(i);
20857            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20858                    "Starting update of " + uidRec);
20859            uidRec.reset();
20860        }
20861
20862        mStackSupervisor.rankTaskLayersIfNeeded();
20863
20864        mAdjSeq++;
20865        mNewNumServiceProcs = 0;
20866        mNewNumAServiceProcs = 0;
20867
20868        final int emptyProcessLimit;
20869        final int cachedProcessLimit;
20870        if (mProcessLimit <= 0) {
20871            emptyProcessLimit = cachedProcessLimit = 0;
20872        } else if (mProcessLimit == 1) {
20873            emptyProcessLimit = 1;
20874            cachedProcessLimit = 0;
20875        } else {
20876            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20877            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20878        }
20879
20880        // Let's determine how many processes we have running vs.
20881        // how many slots we have for background processes; we may want
20882        // to put multiple processes in a slot of there are enough of
20883        // them.
20884        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20885                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20886        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20887        if (numEmptyProcs > cachedProcessLimit) {
20888            // If there are more empty processes than our limit on cached
20889            // processes, then use the cached process limit for the factor.
20890            // This ensures that the really old empty processes get pushed
20891            // down to the bottom, so if we are running low on memory we will
20892            // have a better chance at keeping around more cached processes
20893            // instead of a gazillion empty processes.
20894            numEmptyProcs = cachedProcessLimit;
20895        }
20896        int emptyFactor = numEmptyProcs/numSlots;
20897        if (emptyFactor < 1) emptyFactor = 1;
20898        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20899        if (cachedFactor < 1) cachedFactor = 1;
20900        int stepCached = 0;
20901        int stepEmpty = 0;
20902        int numCached = 0;
20903        int numEmpty = 0;
20904        int numTrimming = 0;
20905
20906        mNumNonCachedProcs = 0;
20907        mNumCachedHiddenProcs = 0;
20908
20909        // First update the OOM adjustment for each of the
20910        // application processes based on their current state.
20911        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20912        int nextCachedAdj = curCachedAdj+1;
20913        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20914        int nextEmptyAdj = curEmptyAdj+2;
20915        for (int i=N-1; i>=0; i--) {
20916            ProcessRecord app = mLruProcesses.get(i);
20917            if (!app.killedByAm && app.thread != null) {
20918                app.procStateChanged = false;
20919                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20920
20921                // If we haven't yet assigned the final cached adj
20922                // to the process, do that now.
20923                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20924                    switch (app.curProcState) {
20925                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20926                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20927                            // This process is a cached process holding activities...
20928                            // assign it the next cached value for that type, and then
20929                            // step that cached level.
20930                            app.curRawAdj = curCachedAdj;
20931                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20932                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20933                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20934                                    + ")");
20935                            if (curCachedAdj != nextCachedAdj) {
20936                                stepCached++;
20937                                if (stepCached >= cachedFactor) {
20938                                    stepCached = 0;
20939                                    curCachedAdj = nextCachedAdj;
20940                                    nextCachedAdj += 2;
20941                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20942                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20943                                    }
20944                                }
20945                            }
20946                            break;
20947                        default:
20948                            // For everything else, assign next empty cached process
20949                            // level and bump that up.  Note that this means that
20950                            // long-running services that have dropped down to the
20951                            // cached level will be treated as empty (since their process
20952                            // state is still as a service), which is what we want.
20953                            app.curRawAdj = curEmptyAdj;
20954                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20955                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20956                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20957                                    + ")");
20958                            if (curEmptyAdj != nextEmptyAdj) {
20959                                stepEmpty++;
20960                                if (stepEmpty >= emptyFactor) {
20961                                    stepEmpty = 0;
20962                                    curEmptyAdj = nextEmptyAdj;
20963                                    nextEmptyAdj += 2;
20964                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20965                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20966                                    }
20967                                }
20968                            }
20969                            break;
20970                    }
20971                }
20972
20973                applyOomAdjLocked(app, true, now, nowElapsed);
20974
20975                // Count the number of process types.
20976                switch (app.curProcState) {
20977                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20978                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20979                        mNumCachedHiddenProcs++;
20980                        numCached++;
20981                        if (numCached > cachedProcessLimit) {
20982                            app.kill("cached #" + numCached, true);
20983                        }
20984                        break;
20985                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20986                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20987                                && app.lastActivityTime < oldTime) {
20988                            app.kill("empty for "
20989                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20990                                    / 1000) + "s", true);
20991                        } else {
20992                            numEmpty++;
20993                            if (numEmpty > emptyProcessLimit) {
20994                                app.kill("empty #" + numEmpty, true);
20995                            }
20996                        }
20997                        break;
20998                    default:
20999                        mNumNonCachedProcs++;
21000                        break;
21001                }
21002
21003                if (app.isolated && app.services.size() <= 0) {
21004                    // If this is an isolated process, and there are no
21005                    // services running in it, then the process is no longer
21006                    // needed.  We agressively kill these because we can by
21007                    // definition not re-use the same process again, and it is
21008                    // good to avoid having whatever code was running in them
21009                    // left sitting around after no longer needed.
21010                    app.kill("isolated not needed", true);
21011                } else {
21012                    // Keeping this process, update its uid.
21013                    final UidRecord uidRec = app.uidRecord;
21014                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
21015                        uidRec.curProcState = app.curProcState;
21016                    }
21017                }
21018
21019                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
21020                        && !app.killedByAm) {
21021                    numTrimming++;
21022                }
21023            }
21024        }
21025
21026        mNumServiceProcs = mNewNumServiceProcs;
21027
21028        // Now determine the memory trimming level of background processes.
21029        // Unfortunately we need to start at the back of the list to do this
21030        // properly.  We only do this if the number of background apps we
21031        // are managing to keep around is less than half the maximum we desire;
21032        // if we are keeping a good number around, we'll let them use whatever
21033        // memory they want.
21034        final int numCachedAndEmpty = numCached + numEmpty;
21035        int memFactor;
21036        if (numCached <= ProcessList.TRIM_CACHED_APPS
21037                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
21038            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
21039                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
21040            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
21041                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
21042            } else {
21043                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
21044            }
21045        } else {
21046            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
21047        }
21048        // We always allow the memory level to go up (better).  We only allow it to go
21049        // down if we are in a state where that is allowed, *and* the total number of processes
21050        // has gone down since last time.
21051        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
21052                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
21053                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
21054        if (memFactor > mLastMemoryLevel) {
21055            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
21056                memFactor = mLastMemoryLevel;
21057                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
21058            }
21059        }
21060        if (memFactor != mLastMemoryLevel) {
21061            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
21062        }
21063        mLastMemoryLevel = memFactor;
21064        mLastNumProcesses = mLruProcesses.size();
21065        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
21066        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
21067        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
21068            if (mLowRamStartTime == 0) {
21069                mLowRamStartTime = now;
21070            }
21071            int step = 0;
21072            int fgTrimLevel;
21073            switch (memFactor) {
21074                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
21075                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
21076                    break;
21077                case ProcessStats.ADJ_MEM_FACTOR_LOW:
21078                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
21079                    break;
21080                default:
21081                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
21082                    break;
21083            }
21084            int factor = numTrimming/3;
21085            int minFactor = 2;
21086            if (mHomeProcess != null) minFactor++;
21087            if (mPreviousProcess != null) minFactor++;
21088            if (factor < minFactor) factor = minFactor;
21089            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
21090            for (int i=N-1; i>=0; i--) {
21091                ProcessRecord app = mLruProcesses.get(i);
21092                if (allChanged || app.procStateChanged) {
21093                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
21094                    app.procStateChanged = false;
21095                }
21096                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
21097                        && !app.killedByAm) {
21098                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
21099                        try {
21100                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21101                                    "Trimming memory of " + app.processName + " to " + curLevel);
21102                            app.thread.scheduleTrimMemory(curLevel);
21103                        } catch (RemoteException e) {
21104                        }
21105                        if (false) {
21106                            // For now we won't do this; our memory trimming seems
21107                            // to be good enough at this point that destroying
21108                            // activities causes more harm than good.
21109                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
21110                                    && app != mHomeProcess && app != mPreviousProcess) {
21111                                // Need to do this on its own message because the stack may not
21112                                // be in a consistent state at this point.
21113                                // For these apps we will also finish their activities
21114                                // to help them free memory.
21115                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
21116                            }
21117                        }
21118                    }
21119                    app.trimMemoryLevel = curLevel;
21120                    step++;
21121                    if (step >= factor) {
21122                        step = 0;
21123                        switch (curLevel) {
21124                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
21125                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
21126                                break;
21127                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
21128                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
21129                                break;
21130                        }
21131                    }
21132                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
21133                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
21134                            && app.thread != null) {
21135                        try {
21136                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21137                                    "Trimming memory of heavy-weight " + app.processName
21138                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
21139                            app.thread.scheduleTrimMemory(
21140                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
21141                        } catch (RemoteException e) {
21142                        }
21143                    }
21144                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
21145                } else {
21146                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21147                            || app.systemNoUi) && app.pendingUiClean) {
21148                        // If this application is now in the background and it
21149                        // had done UI, then give it the special trim level to
21150                        // have it free UI resources.
21151                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
21152                        if (app.trimMemoryLevel < level && app.thread != null) {
21153                            try {
21154                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21155                                        "Trimming memory of bg-ui " + app.processName
21156                                        + " to " + level);
21157                                app.thread.scheduleTrimMemory(level);
21158                            } catch (RemoteException e) {
21159                            }
21160                        }
21161                        app.pendingUiClean = false;
21162                    }
21163                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
21164                        try {
21165                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21166                                    "Trimming memory of fg " + app.processName
21167                                    + " to " + fgTrimLevel);
21168                            app.thread.scheduleTrimMemory(fgTrimLevel);
21169                        } catch (RemoteException e) {
21170                        }
21171                    }
21172                    app.trimMemoryLevel = fgTrimLevel;
21173                }
21174            }
21175        } else {
21176            if (mLowRamStartTime != 0) {
21177                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
21178                mLowRamStartTime = 0;
21179            }
21180            for (int i=N-1; i>=0; i--) {
21181                ProcessRecord app = mLruProcesses.get(i);
21182                if (allChanged || app.procStateChanged) {
21183                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
21184                    app.procStateChanged = false;
21185                }
21186                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21187                        || app.systemNoUi) && app.pendingUiClean) {
21188                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
21189                            && app.thread != null) {
21190                        try {
21191                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21192                                    "Trimming memory of ui hidden " + app.processName
21193                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
21194                            app.thread.scheduleTrimMemory(
21195                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
21196                        } catch (RemoteException e) {
21197                        }
21198                    }
21199                    app.pendingUiClean = false;
21200                }
21201                app.trimMemoryLevel = 0;
21202            }
21203        }
21204
21205        if (mAlwaysFinishActivities) {
21206            // Need to do this on its own message because the stack may not
21207            // be in a consistent state at this point.
21208            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
21209        }
21210
21211        if (allChanged) {
21212            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
21213        }
21214
21215        // Update from any uid changes.
21216        for (int i=mActiveUids.size()-1; i>=0; i--) {
21217            final UidRecord uidRec = mActiveUids.valueAt(i);
21218            int uidChange = UidRecord.CHANGE_PROCSTATE;
21219            if (uidRec.setProcState != uidRec.curProcState) {
21220                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21221                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
21222                        + " to " + uidRec.curProcState);
21223                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
21224                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
21225                        uidRec.lastBackgroundTime = nowElapsed;
21226                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
21227                            // Note: the background settle time is in elapsed realtime, while
21228                            // the handler time base is uptime.  All this means is that we may
21229                            // stop background uids later than we had intended, but that only
21230                            // happens because the device was sleeping so we are okay anyway.
21231                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
21232                        }
21233                    }
21234                } else {
21235                    if (uidRec.idle) {
21236                        uidChange = UidRecord.CHANGE_ACTIVE;
21237                        uidRec.idle = false;
21238                    }
21239                    uidRec.lastBackgroundTime = 0;
21240                }
21241                uidRec.setProcState = uidRec.curProcState;
21242                enqueueUidChangeLocked(uidRec, -1, uidChange);
21243                noteUidProcessState(uidRec.uid, uidRec.curProcState);
21244            }
21245        }
21246
21247        if (mProcessStats.shouldWriteNowLocked(now)) {
21248            mHandler.post(new Runnable() {
21249                @Override public void run() {
21250                    synchronized (ActivityManagerService.this) {
21251                        mProcessStats.writeStateAsyncLocked();
21252                    }
21253                }
21254            });
21255        }
21256
21257        if (DEBUG_OOM_ADJ) {
21258            final long duration = SystemClock.uptimeMillis() - now;
21259            if (false) {
21260                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
21261                        new RuntimeException("here").fillInStackTrace());
21262            } else {
21263                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
21264            }
21265        }
21266    }
21267
21268    final void idleUids() {
21269        synchronized (this) {
21270            final long nowElapsed = SystemClock.elapsedRealtime();
21271            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
21272            long nextTime = 0;
21273            for (int i=mActiveUids.size()-1; i>=0; i--) {
21274                final UidRecord uidRec = mActiveUids.valueAt(i);
21275                final long bgTime = uidRec.lastBackgroundTime;
21276                if (bgTime > 0 && !uidRec.idle) {
21277                    if (bgTime <= maxBgTime) {
21278                        uidRec.idle = true;
21279                        doStopUidLocked(uidRec.uid, uidRec);
21280                    } else {
21281                        if (nextTime == 0 || nextTime > bgTime) {
21282                            nextTime = bgTime;
21283                        }
21284                    }
21285                }
21286            }
21287            if (nextTime > 0) {
21288                mHandler.removeMessages(IDLE_UIDS_MSG);
21289                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
21290                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
21291            }
21292        }
21293    }
21294
21295    final void runInBackgroundDisabled(int uid) {
21296        synchronized (this) {
21297            UidRecord uidRec = mActiveUids.get(uid);
21298            if (uidRec != null) {
21299                // This uid is actually running...  should it be considered background now?
21300                if (uidRec.idle) {
21301                    doStopUidLocked(uidRec.uid, uidRec);
21302                }
21303            } else {
21304                // This uid isn't actually running...  still send a report about it being "stopped".
21305                doStopUidLocked(uid, null);
21306            }
21307        }
21308    }
21309
21310    final void doStopUidLocked(int uid, final UidRecord uidRec) {
21311        mServices.stopInBackgroundLocked(uid);
21312        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
21313    }
21314
21315    final void trimApplications() {
21316        synchronized (this) {
21317            int i;
21318
21319            // First remove any unused application processes whose package
21320            // has been removed.
21321            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
21322                final ProcessRecord app = mRemovedProcesses.get(i);
21323                if (app.activities.size() == 0
21324                        && app.curReceiver == null && app.services.size() == 0) {
21325                    Slog.i(
21326                        TAG, "Exiting empty application process "
21327                        + app.toShortString() + " ("
21328                        + (app.thread != null ? app.thread.asBinder() : null)
21329                        + ")\n");
21330                    if (app.pid > 0 && app.pid != MY_PID) {
21331                        app.kill("empty", false);
21332                    } else {
21333                        try {
21334                            app.thread.scheduleExit();
21335                        } catch (Exception e) {
21336                            // Ignore exceptions.
21337                        }
21338                    }
21339                    cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
21340                    mRemovedProcesses.remove(i);
21341
21342                    if (app.persistent) {
21343                        addAppLocked(app.info, false, null /* ABI override */);
21344                    }
21345                }
21346            }
21347
21348            // Now update the oom adj for all processes.
21349            updateOomAdjLocked();
21350        }
21351    }
21352
21353    /** This method sends the specified signal to each of the persistent apps */
21354    public void signalPersistentProcesses(int sig) throws RemoteException {
21355        if (sig != Process.SIGNAL_USR1) {
21356            throw new SecurityException("Only SIGNAL_USR1 is allowed");
21357        }
21358
21359        synchronized (this) {
21360            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
21361                    != PackageManager.PERMISSION_GRANTED) {
21362                throw new SecurityException("Requires permission "
21363                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
21364            }
21365
21366            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
21367                ProcessRecord r = mLruProcesses.get(i);
21368                if (r.thread != null && r.persistent) {
21369                    Process.sendSignal(r.pid, sig);
21370                }
21371            }
21372        }
21373    }
21374
21375    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
21376        if (proc == null || proc == mProfileProc) {
21377            proc = mProfileProc;
21378            profileType = mProfileType;
21379            clearProfilerLocked();
21380        }
21381        if (proc == null) {
21382            return;
21383        }
21384        try {
21385            proc.thread.profilerControl(false, null, profileType);
21386        } catch (RemoteException e) {
21387            throw new IllegalStateException("Process disappeared");
21388        }
21389    }
21390
21391    private void clearProfilerLocked() {
21392        if (mProfileFd != null) {
21393            try {
21394                mProfileFd.close();
21395            } catch (IOException e) {
21396            }
21397        }
21398        mProfileApp = null;
21399        mProfileProc = null;
21400        mProfileFile = null;
21401        mProfileType = 0;
21402        mAutoStopProfiler = false;
21403        mSamplingInterval = 0;
21404    }
21405
21406    public boolean profileControl(String process, int userId, boolean start,
21407            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
21408
21409        try {
21410            synchronized (this) {
21411                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21412                // its own permission.
21413                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21414                        != PackageManager.PERMISSION_GRANTED) {
21415                    throw new SecurityException("Requires permission "
21416                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21417                }
21418
21419                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
21420                    throw new IllegalArgumentException("null profile info or fd");
21421                }
21422
21423                ProcessRecord proc = null;
21424                if (process != null) {
21425                    proc = findProcessLocked(process, userId, "profileControl");
21426                }
21427
21428                if (start && (proc == null || proc.thread == null)) {
21429                    throw new IllegalArgumentException("Unknown process: " + process);
21430                }
21431
21432                if (start) {
21433                    stopProfilerLocked(null, 0);
21434                    setProfileApp(proc.info, proc.processName, profilerInfo);
21435                    mProfileProc = proc;
21436                    mProfileType = profileType;
21437                    ParcelFileDescriptor fd = profilerInfo.profileFd;
21438                    try {
21439                        fd = fd.dup();
21440                    } catch (IOException e) {
21441                        fd = null;
21442                    }
21443                    profilerInfo.profileFd = fd;
21444                    proc.thread.profilerControl(start, profilerInfo, profileType);
21445                    fd = null;
21446                    mProfileFd = null;
21447                } else {
21448                    stopProfilerLocked(proc, profileType);
21449                    if (profilerInfo != null && profilerInfo.profileFd != null) {
21450                        try {
21451                            profilerInfo.profileFd.close();
21452                        } catch (IOException e) {
21453                        }
21454                    }
21455                }
21456
21457                return true;
21458            }
21459        } catch (RemoteException e) {
21460            throw new IllegalStateException("Process disappeared");
21461        } finally {
21462            if (profilerInfo != null && profilerInfo.profileFd != null) {
21463                try {
21464                    profilerInfo.profileFd.close();
21465                } catch (IOException e) {
21466                }
21467            }
21468        }
21469    }
21470
21471    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
21472        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
21473                userId, true, ALLOW_FULL_ONLY, callName, null);
21474        ProcessRecord proc = null;
21475        try {
21476            int pid = Integer.parseInt(process);
21477            synchronized (mPidsSelfLocked) {
21478                proc = mPidsSelfLocked.get(pid);
21479            }
21480        } catch (NumberFormatException e) {
21481        }
21482
21483        if (proc == null) {
21484            ArrayMap<String, SparseArray<ProcessRecord>> all
21485                    = mProcessNames.getMap();
21486            SparseArray<ProcessRecord> procs = all.get(process);
21487            if (procs != null && procs.size() > 0) {
21488                proc = procs.valueAt(0);
21489                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
21490                    for (int i=1; i<procs.size(); i++) {
21491                        ProcessRecord thisProc = procs.valueAt(i);
21492                        if (thisProc.userId == userId) {
21493                            proc = thisProc;
21494                            break;
21495                        }
21496                    }
21497                }
21498            }
21499        }
21500
21501        return proc;
21502    }
21503
21504    public boolean dumpHeap(String process, int userId, boolean managed,
21505            String path, ParcelFileDescriptor fd) throws RemoteException {
21506
21507        try {
21508            synchronized (this) {
21509                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21510                // its own permission (same as profileControl).
21511                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21512                        != PackageManager.PERMISSION_GRANTED) {
21513                    throw new SecurityException("Requires permission "
21514                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21515                }
21516
21517                if (fd == null) {
21518                    throw new IllegalArgumentException("null fd");
21519                }
21520
21521                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
21522                if (proc == null || proc.thread == null) {
21523                    throw new IllegalArgumentException("Unknown process: " + process);
21524                }
21525
21526                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21527                if (!isDebuggable) {
21528                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21529                        throw new SecurityException("Process not debuggable: " + proc);
21530                    }
21531                }
21532
21533                proc.thread.dumpHeap(managed, path, fd);
21534                fd = null;
21535                return true;
21536            }
21537        } catch (RemoteException e) {
21538            throw new IllegalStateException("Process disappeared");
21539        } finally {
21540            if (fd != null) {
21541                try {
21542                    fd.close();
21543                } catch (IOException e) {
21544                }
21545            }
21546        }
21547    }
21548
21549    @Override
21550    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
21551            String reportPackage) {
21552        if (processName != null) {
21553            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
21554                    "setDumpHeapDebugLimit()");
21555        } else {
21556            synchronized (mPidsSelfLocked) {
21557                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
21558                if (proc == null) {
21559                    throw new SecurityException("No process found for calling pid "
21560                            + Binder.getCallingPid());
21561                }
21562                if (!Build.IS_DEBUGGABLE
21563                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21564                    throw new SecurityException("Not running a debuggable build");
21565                }
21566                processName = proc.processName;
21567                uid = proc.uid;
21568                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
21569                    throw new SecurityException("Package " + reportPackage + " is not running in "
21570                            + proc);
21571                }
21572            }
21573        }
21574        synchronized (this) {
21575            if (maxMemSize > 0) {
21576                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
21577            } else {
21578                if (uid != 0) {
21579                    mMemWatchProcesses.remove(processName, uid);
21580                } else {
21581                    mMemWatchProcesses.getMap().remove(processName);
21582                }
21583            }
21584        }
21585    }
21586
21587    @Override
21588    public void dumpHeapFinished(String path) {
21589        synchronized (this) {
21590            if (Binder.getCallingPid() != mMemWatchDumpPid) {
21591                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
21592                        + " does not match last pid " + mMemWatchDumpPid);
21593                return;
21594            }
21595            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
21596                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
21597                        + " does not match last path " + mMemWatchDumpFile);
21598                return;
21599            }
21600            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
21601            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
21602        }
21603    }
21604
21605    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
21606    public void monitor() {
21607        synchronized (this) { }
21608    }
21609
21610    void onCoreSettingsChange(Bundle settings) {
21611        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21612            ProcessRecord processRecord = mLruProcesses.get(i);
21613            try {
21614                if (processRecord.thread != null) {
21615                    processRecord.thread.setCoreSettings(settings);
21616                }
21617            } catch (RemoteException re) {
21618                /* ignore */
21619            }
21620        }
21621    }
21622
21623    // Multi-user methods
21624
21625    /**
21626     * Start user, if its not already running, but don't bring it to foreground.
21627     */
21628    @Override
21629    public boolean startUserInBackground(final int userId) {
21630        return mUserController.startUser(userId, /* foreground */ false);
21631    }
21632
21633    @Override
21634    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
21635        return mUserController.unlockUser(userId, token, secret, listener);
21636    }
21637
21638    @Override
21639    public boolean switchUser(final int targetUserId) {
21640        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
21641        UserInfo currentUserInfo;
21642        UserInfo targetUserInfo;
21643        synchronized (this) {
21644            int currentUserId = mUserController.getCurrentUserIdLocked();
21645            currentUserInfo = mUserController.getUserInfo(currentUserId);
21646            targetUserInfo = mUserController.getUserInfo(targetUserId);
21647            if (targetUserInfo == null) {
21648                Slog.w(TAG, "No user info for user #" + targetUserId);
21649                return false;
21650            }
21651            if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
21652                Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
21653                        + " when device is in demo mode");
21654                return false;
21655            }
21656            if (!targetUserInfo.supportsSwitchTo()) {
21657                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
21658                return false;
21659            }
21660            if (targetUserInfo.isManagedProfile()) {
21661                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
21662                return false;
21663            }
21664            mUserController.setTargetUserIdLocked(targetUserId);
21665        }
21666        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
21667        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
21668        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
21669        return true;
21670    }
21671
21672    void scheduleStartProfilesLocked() {
21673        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
21674            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
21675                    DateUtils.SECOND_IN_MILLIS);
21676        }
21677    }
21678
21679    @Override
21680    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
21681        return mUserController.stopUser(userId, force, callback);
21682    }
21683
21684    @Override
21685    public UserInfo getCurrentUser() {
21686        return mUserController.getCurrentUser();
21687    }
21688
21689    @Override
21690    public boolean isUserRunning(int userId, int flags) {
21691        if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
21692                && checkCallingPermission(INTERACT_ACROSS_USERS)
21693                    != PackageManager.PERMISSION_GRANTED) {
21694            String msg = "Permission Denial: isUserRunning() from pid="
21695                    + Binder.getCallingPid()
21696                    + ", uid=" + Binder.getCallingUid()
21697                    + " requires " + INTERACT_ACROSS_USERS;
21698            Slog.w(TAG, msg);
21699            throw new SecurityException(msg);
21700        }
21701        synchronized (this) {
21702            return mUserController.isUserRunningLocked(userId, flags);
21703        }
21704    }
21705
21706    @Override
21707    public int[] getRunningUserIds() {
21708        if (checkCallingPermission(INTERACT_ACROSS_USERS)
21709                != PackageManager.PERMISSION_GRANTED) {
21710            String msg = "Permission Denial: isUserRunning() from pid="
21711                    + Binder.getCallingPid()
21712                    + ", uid=" + Binder.getCallingUid()
21713                    + " requires " + INTERACT_ACROSS_USERS;
21714            Slog.w(TAG, msg);
21715            throw new SecurityException(msg);
21716        }
21717        synchronized (this) {
21718            return mUserController.getStartedUserArrayLocked();
21719        }
21720    }
21721
21722    @Override
21723    public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
21724        mUserController.registerUserSwitchObserver(observer, name);
21725    }
21726
21727    @Override
21728    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
21729        mUserController.unregisterUserSwitchObserver(observer);
21730    }
21731
21732    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
21733        if (info == null) return null;
21734        ApplicationInfo newInfo = new ApplicationInfo(info);
21735        newInfo.initForUser(userId);
21736        return newInfo;
21737    }
21738
21739    public boolean isUserStopped(int userId) {
21740        synchronized (this) {
21741            return mUserController.getStartedUserStateLocked(userId) == null;
21742        }
21743    }
21744
21745    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
21746        if (aInfo == null
21747                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
21748            return aInfo;
21749        }
21750
21751        ActivityInfo info = new ActivityInfo(aInfo);
21752        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
21753        return info;
21754    }
21755
21756    private boolean processSanityChecksLocked(ProcessRecord process) {
21757        if (process == null || process.thread == null) {
21758            return false;
21759        }
21760
21761        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21762        if (!isDebuggable) {
21763            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21764                return false;
21765            }
21766        }
21767
21768        return true;
21769    }
21770
21771    public boolean startBinderTracking() throws RemoteException {
21772        synchronized (this) {
21773            mBinderTransactionTrackingEnabled = true;
21774            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21775            // permission (same as profileControl).
21776            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21777                    != PackageManager.PERMISSION_GRANTED) {
21778                throw new SecurityException("Requires permission "
21779                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21780            }
21781
21782            for (int i = 0; i < mLruProcesses.size(); i++) {
21783                ProcessRecord process = mLruProcesses.get(i);
21784                if (!processSanityChecksLocked(process)) {
21785                    continue;
21786                }
21787                try {
21788                    process.thread.startBinderTracking();
21789                } catch (RemoteException e) {
21790                    Log.v(TAG, "Process disappared");
21791                }
21792            }
21793            return true;
21794        }
21795    }
21796
21797    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
21798        try {
21799            synchronized (this) {
21800                mBinderTransactionTrackingEnabled = false;
21801                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21802                // permission (same as profileControl).
21803                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21804                        != PackageManager.PERMISSION_GRANTED) {
21805                    throw new SecurityException("Requires permission "
21806                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21807                }
21808
21809                if (fd == null) {
21810                    throw new IllegalArgumentException("null fd");
21811                }
21812
21813                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
21814                pw.println("Binder transaction traces for all processes.\n");
21815                for (ProcessRecord process : mLruProcesses) {
21816                    if (!processSanityChecksLocked(process)) {
21817                        continue;
21818                    }
21819
21820                    pw.println("Traces for process: " + process.processName);
21821                    pw.flush();
21822                    try {
21823                        TransferPipe tp = new TransferPipe();
21824                        try {
21825                            process.thread.stopBinderTrackingAndDump(
21826                                    tp.getWriteFd().getFileDescriptor());
21827                            tp.go(fd.getFileDescriptor());
21828                        } finally {
21829                            tp.kill();
21830                        }
21831                    } catch (IOException e) {
21832                        pw.println("Failure while dumping IPC traces from " + process +
21833                                ".  Exception: " + e);
21834                        pw.flush();
21835                    } catch (RemoteException e) {
21836                        pw.println("Got a RemoteException while dumping IPC traces from " +
21837                                process + ".  Exception: " + e);
21838                        pw.flush();
21839                    }
21840                }
21841                fd = null;
21842                return true;
21843            }
21844        } finally {
21845            if (fd != null) {
21846                try {
21847                    fd.close();
21848                } catch (IOException e) {
21849                }
21850            }
21851        }
21852    }
21853
21854    private final class LocalService extends ActivityManagerInternal {
21855        @Override
21856        public void onWakefulnessChanged(int wakefulness) {
21857            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21858        }
21859
21860        @Override
21861        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21862                String processName, String abiOverride, int uid, Runnable crashHandler) {
21863            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21864                    processName, abiOverride, uid, crashHandler);
21865        }
21866
21867        @Override
21868        public SleepToken acquireSleepToken(String tag) {
21869            Preconditions.checkNotNull(tag);
21870
21871            ComponentName requestedVrService = null;
21872            ComponentName callingVrActivity = null;
21873            int userId = -1;
21874            synchronized (ActivityManagerService.this) {
21875                if (mFocusedActivity != null) {
21876                    requestedVrService = mFocusedActivity.requestedVrComponent;
21877                    callingVrActivity = mFocusedActivity.info.getComponentName();
21878                    userId = mFocusedActivity.userId;
21879                }
21880            }
21881
21882            if (requestedVrService != null) {
21883                applyVrMode(false, requestedVrService, userId, callingVrActivity, true);
21884            }
21885
21886            synchronized (ActivityManagerService.this) {
21887                SleepTokenImpl token = new SleepTokenImpl(tag);
21888                mSleepTokens.add(token);
21889                updateSleepIfNeededLocked();
21890                return token;
21891            }
21892        }
21893
21894        @Override
21895        public ComponentName getHomeActivityForUser(int userId) {
21896            synchronized (ActivityManagerService.this) {
21897                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21898                return homeActivity == null ? null : homeActivity.realActivity;
21899            }
21900        }
21901
21902        @Override
21903        public void onUserRemoved(int userId) {
21904            synchronized (ActivityManagerService.this) {
21905                ActivityManagerService.this.onUserStoppedLocked(userId);
21906            }
21907        }
21908
21909        @Override
21910        public void onLocalVoiceInteractionStarted(IBinder activity,
21911                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
21912            synchronized (ActivityManagerService.this) {
21913                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21914                        voiceSession, voiceInteractor);
21915            }
21916        }
21917
21918        @Override
21919        public void notifyStartingWindowDrawn() {
21920            synchronized (ActivityManagerService.this) {
21921                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
21922            }
21923        }
21924
21925        @Override
21926        public void notifyAppTransitionStarting(int reason) {
21927            synchronized (ActivityManagerService.this) {
21928                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
21929            }
21930        }
21931
21932        @Override
21933        public void notifyAppTransitionFinished() {
21934            synchronized (ActivityManagerService.this) {
21935                mStackSupervisor.notifyAppTransitionDone();
21936            }
21937        }
21938
21939        @Override
21940        public void notifyAppTransitionCancelled() {
21941            synchronized (ActivityManagerService.this) {
21942                mStackSupervisor.notifyAppTransitionDone();
21943            }
21944        }
21945
21946        @Override
21947        public List<IBinder> getTopVisibleActivities() {
21948            synchronized (ActivityManagerService.this) {
21949                return mStackSupervisor.getTopVisibleActivities();
21950            }
21951        }
21952
21953        @Override
21954        public void notifyDockedStackMinimizedChanged(boolean minimized) {
21955            synchronized (ActivityManagerService.this) {
21956                mStackSupervisor.setDockedStackMinimized(minimized);
21957            }
21958        }
21959
21960        @Override
21961        public void killForegroundAppsForUser(int userHandle) {
21962            synchronized (ActivityManagerService.this) {
21963                final ArrayList<ProcessRecord> procs = new ArrayList<>();
21964                final int NP = mProcessNames.getMap().size();
21965                for (int ip = 0; ip < NP; ip++) {
21966                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
21967                    final int NA = apps.size();
21968                    for (int ia = 0; ia < NA; ia++) {
21969                        final ProcessRecord app = apps.valueAt(ia);
21970                        if (app.persistent) {
21971                            // We don't kill persistent processes.
21972                            continue;
21973                        }
21974                        if (app.removed) {
21975                            procs.add(app);
21976                        } else if (app.userId == userHandle && app.foregroundActivities) {
21977                            app.removed = true;
21978                            procs.add(app);
21979                        }
21980                    }
21981                }
21982
21983                final int N = procs.size();
21984                for (int i = 0; i < N; i++) {
21985                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
21986                }
21987            }
21988        }
21989
21990        @Override
21991        public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
21992            if (!(target instanceof PendingIntentRecord)) {
21993                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
21994                return;
21995            }
21996            ((PendingIntentRecord) target).setWhitelistDuration(duration);
21997        }
21998
21999        @Override
22000        public void updatePersistentConfigurationForUser(@NonNull Configuration values,
22001                int userId) {
22002            Preconditions.checkNotNull(values, "Configuration must not be null");
22003            Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
22004            synchronized (ActivityManagerService.this) {
22005                updateConfigurationLocked(values, null, false, true, userId,
22006                        false /* deferResume */);
22007            }
22008        }
22009
22010        @Override
22011        public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
22012                Bundle bOptions) {
22013            Preconditions.checkNotNull(intents, "intents");
22014            final String[] resolvedTypes = new String[intents.length];
22015            for (int i = 0; i < intents.length; i++) {
22016                resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
22017            }
22018
22019            // UID of the package on user userId.
22020            // "= 0" is needed because otherwise catch(RemoteException) would make it look like
22021            // packageUid may not be initialized.
22022            int packageUid = 0;
22023            try {
22024                packageUid = AppGlobals.getPackageManager().getPackageUid(
22025                        packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
22026            } catch (RemoteException e) {
22027                // Shouldn't happen.
22028            }
22029
22030            synchronized (ActivityManagerService.this) {
22031                return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
22032                        /*resultTo*/ null, bOptions, userId);
22033            }
22034        }
22035
22036        @Override
22037        public int getUidProcessState(int uid) {
22038            return getUidState(uid);
22039        }
22040    }
22041
22042    private final class SleepTokenImpl extends SleepToken {
22043        private final String mTag;
22044        private final long mAcquireTime;
22045
22046        public SleepTokenImpl(String tag) {
22047            mTag = tag;
22048            mAcquireTime = SystemClock.uptimeMillis();
22049        }
22050
22051        @Override
22052        public void release() {
22053            synchronized (ActivityManagerService.this) {
22054                if (mSleepTokens.remove(this)) {
22055                    updateSleepIfNeededLocked();
22056                }
22057            }
22058        }
22059
22060        @Override
22061        public String toString() {
22062            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
22063        }
22064    }
22065
22066    /**
22067     * An implementation of IAppTask, that allows an app to manage its own tasks via
22068     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
22069     * only the process that calls getAppTasks() can call the AppTask methods.
22070     */
22071    class AppTaskImpl extends IAppTask.Stub {
22072        private int mTaskId;
22073        private int mCallingUid;
22074
22075        public AppTaskImpl(int taskId, int callingUid) {
22076            mTaskId = taskId;
22077            mCallingUid = callingUid;
22078        }
22079
22080        private void checkCaller() {
22081            if (mCallingUid != Binder.getCallingUid()) {
22082                throw new SecurityException("Caller " + mCallingUid
22083                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
22084            }
22085        }
22086
22087        @Override
22088        public void finishAndRemoveTask() {
22089            checkCaller();
22090
22091            synchronized (ActivityManagerService.this) {
22092                long origId = Binder.clearCallingIdentity();
22093                try {
22094                    // We remove the task from recents to preserve backwards
22095                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
22096                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22097                    }
22098                } finally {
22099                    Binder.restoreCallingIdentity(origId);
22100                }
22101            }
22102        }
22103
22104        @Override
22105        public ActivityManager.RecentTaskInfo getTaskInfo() {
22106            checkCaller();
22107
22108            synchronized (ActivityManagerService.this) {
22109                long origId = Binder.clearCallingIdentity();
22110                try {
22111                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22112                    if (tr == null) {
22113                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22114                    }
22115                    return createRecentTaskInfoFromTaskRecord(tr);
22116                } finally {
22117                    Binder.restoreCallingIdentity(origId);
22118                }
22119            }
22120        }
22121
22122        @Override
22123        public void moveToFront() {
22124            checkCaller();
22125            // Will bring task to front if it already has a root activity.
22126            final long origId = Binder.clearCallingIdentity();
22127            try {
22128                synchronized (this) {
22129                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
22130                }
22131            } finally {
22132                Binder.restoreCallingIdentity(origId);
22133            }
22134        }
22135
22136        @Override
22137        public int startActivity(IBinder whoThread, String callingPackage,
22138                Intent intent, String resolvedType, Bundle bOptions) {
22139            checkCaller();
22140
22141            int callingUser = UserHandle.getCallingUserId();
22142            TaskRecord tr;
22143            IApplicationThread appThread;
22144            synchronized (ActivityManagerService.this) {
22145                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22146                if (tr == null) {
22147                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22148                }
22149                appThread = ApplicationThreadNative.asInterface(whoThread);
22150                if (appThread == null) {
22151                    throw new IllegalArgumentException("Bad app thread " + appThread);
22152                }
22153            }
22154            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
22155                    resolvedType, null, null, null, null, 0, 0, null, null,
22156                    null, bOptions, false, callingUser, null, tr);
22157        }
22158
22159        @Override
22160        public void setExcludeFromRecents(boolean exclude) {
22161            checkCaller();
22162
22163            synchronized (ActivityManagerService.this) {
22164                long origId = Binder.clearCallingIdentity();
22165                try {
22166                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22167                    if (tr == null) {
22168                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22169                    }
22170                    Intent intent = tr.getBaseIntent();
22171                    if (exclude) {
22172                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
22173                    } else {
22174                        intent.setFlags(intent.getFlags()
22175                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
22176                    }
22177                } finally {
22178                    Binder.restoreCallingIdentity(origId);
22179                }
22180            }
22181        }
22182    }
22183
22184    /**
22185     * Kill processes for the user with id userId and that depend on the package named packageName
22186     */
22187    @Override
22188    public void killPackageDependents(String packageName, int userId) {
22189        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
22190        if (packageName == null) {
22191            throw new NullPointerException(
22192                    "Cannot kill the dependents of a package without its name.");
22193        }
22194
22195        long callingId = Binder.clearCallingIdentity();
22196        IPackageManager pm = AppGlobals.getPackageManager();
22197        int pkgUid = -1;
22198        try {
22199            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
22200        } catch (RemoteException e) {
22201        }
22202        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
22203            throw new IllegalArgumentException(
22204                    "Cannot kill dependents of non-existing package " + packageName);
22205        }
22206        try {
22207            synchronized(this) {
22208                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
22209                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
22210                        "dep: " + packageName);
22211            }
22212        } finally {
22213            Binder.restoreCallingIdentity(callingId);
22214        }
22215    }
22216
22217    @Override
22218    public boolean canBypassWorkChallenge(PendingIntent intent) throws RemoteException {
22219        final int userId = intent.getCreatorUserHandle().getIdentifier();
22220        if (!mUserController.isUserRunningLocked(userId, ActivityManager.FLAG_AND_LOCKED)) {
22221            return false;
22222        }
22223        IIntentSender target = intent.getTarget();
22224        if (!(target instanceof PendingIntentRecord)) {
22225            return false;
22226        }
22227        final PendingIntentRecord record = (PendingIntentRecord) target;
22228        final ResolveInfo rInfo = mStackSupervisor.resolveIntent(record.key.requestIntent,
22229                record.key.requestResolvedType, userId, PackageManager.MATCH_DIRECT_BOOT_AWARE);
22230        // For direct boot aware activities, they can be shown without triggering a work challenge
22231        // before the profile user is unlocked.
22232        return rInfo != null && rInfo.activityInfo != null;
22233    }
22234}
22235