ActivityManagerService.java revision 4df43ad959a01beb1240549c8358a27bad975c09
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.util.ArrayUtils;
39import com.android.internal.util.FastPrintWriter;
40import com.android.internal.util.FastXmlSerializer;
41import com.android.internal.util.MemInfoReader;
42import com.android.internal.util.Preconditions;
43import com.android.server.AppOpsService;
44import com.android.server.AttributeCache;
45import com.android.server.DeviceIdleController;
46import com.android.server.IntentResolver;
47import com.android.server.LocalServices;
48import com.android.server.LockGuard;
49import com.android.server.ServiceThread;
50import com.android.server.SystemService;
51import com.android.server.SystemServiceManager;
52import com.android.server.Watchdog;
53import com.android.server.am.ActivityStack.ActivityState;
54import com.android.server.firewall.IntentFirewall;
55import com.android.server.pm.Installer;
56import com.android.server.pm.Installer.InstallerException;
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.os.storage.IMountService;
194import android.os.storage.MountServiceInternal;
195import android.os.storage.StorageManager;
196import android.provider.Settings;
197import android.service.voice.IVoiceInteractionSession;
198import android.service.voice.VoiceInteractionManagerInternal;
199import android.service.voice.VoiceInteractionSession;
200import android.telecom.TelecomManager;
201import android.text.format.DateUtils;
202import android.text.format.Time;
203import android.text.style.SuggestionSpan;
204import android.util.ArrayMap;
205import android.util.ArraySet;
206import android.util.AtomicFile;
207import android.util.DebugUtils;
208import android.util.DisplayMetrics;
209import android.util.EventLog;
210import android.util.Log;
211import android.util.Pair;
212import android.util.PrintWriterPrinter;
213import android.util.Slog;
214import android.util.SparseArray;
215import android.util.TimeUtils;
216import android.util.Xml;
217import android.view.Display;
218import android.view.Gravity;
219import android.view.LayoutInflater;
220import android.view.View;
221import android.view.WindowManager;
222
223import java.io.File;
224import java.io.FileDescriptor;
225import java.io.FileInputStream;
226import java.io.FileNotFoundException;
227import java.io.FileOutputStream;
228import java.io.IOException;
229import java.io.InputStreamReader;
230import java.io.PrintWriter;
231import java.io.StringWriter;
232import java.lang.ref.WeakReference;
233import java.nio.charset.StandardCharsets;
234import java.util.ArrayList;
235import java.util.Arrays;
236import java.util.Collections;
237import java.util.Comparator;
238import java.util.HashMap;
239import java.util.HashSet;
240import java.util.Iterator;
241import java.util.List;
242import java.util.Locale;
243import java.util.Map;
244import java.util.Objects;
245import java.util.Set;
246import java.util.concurrent.atomic.AtomicBoolean;
247import java.util.concurrent.atomic.AtomicLong;
248
249import dalvik.system.VMRuntime;
250
251import libcore.io.IoUtils;
252import libcore.util.EmptyArray;
253
254import static android.Manifest.permission.INTERACT_ACROSS_USERS;
255import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
256import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
257import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
258import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
259import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
260import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
261import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
262import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
263import static android.app.ActivityManager.StackId.HOME_STACK_ID;
264import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
265import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
266import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
267import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
268import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
269import static android.content.pm.PackageManager.GET_PROVIDERS;
270import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
271import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
272import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
273import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
274import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
275import static android.content.pm.PackageManager.PERMISSION_GRANTED;
276import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
277import static android.os.Process.PROC_CHAR;
278import static android.os.Process.PROC_OUT_LONG;
279import static android.os.Process.PROC_PARENS;
280import static android.os.Process.PROC_SPACE_TERM;
281import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
282import static android.provider.Settings.Global.DEBUG_APP;
283import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
284import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
285import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
286import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
287import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
288import static android.provider.Settings.System.FONT_SCALE;
289import static com.android.internal.util.XmlUtils.readBooleanAttribute;
290import static com.android.internal.util.XmlUtils.readIntAttribute;
291import static com.android.internal.util.XmlUtils.readLongAttribute;
292import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
293import static com.android.internal.util.XmlUtils.writeIntAttribute;
294import static com.android.internal.util.XmlUtils.writeLongAttribute;
295import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
296import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
297import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
298import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
299import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
300import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
301import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
302import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
303import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
304import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
305import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
306import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
307import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
308import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
309import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
310import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
311import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
312import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
313import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
314import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
315import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
316import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
317import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
318import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
319import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
320import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
321import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
322import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
323import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
324import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
325import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
326import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
327import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
328import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
329import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
330import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
331import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
332import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
333import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
334import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
335import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
336import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
337import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
338import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
339import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
340import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
341import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
342import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
343import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
344import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
345import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
346import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
347import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
348import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
349import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
350import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
351import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
352import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
353import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
354import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
355import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
356import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
357import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
358import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
359import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
360import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
361import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
362import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
363import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
364import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
365import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
366import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
367import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
368import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
369import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
370import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
371import static org.xmlpull.v1.XmlPullParser.START_TAG;
372
373public final class ActivityManagerService extends ActivityManagerNative
374        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
375
376    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
377    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
378    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
379    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
380    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
381    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
382    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
383    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
384    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
385    private static final String TAG_LRU = TAG + POSTFIX_LRU;
386    private static final String TAG_MU = TAG + POSTFIX_MU;
387    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
388    private static final String TAG_POWER = TAG + POSTFIX_POWER;
389    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
390    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
391    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
392    private static final String TAG_PSS = TAG + POSTFIX_PSS;
393    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
394    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
395    private static final String TAG_STACK = TAG + POSTFIX_STACK;
396    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
397    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
398    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
399    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
400    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
401
402    // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
403    // here so that while the job scheduler can depend on AMS, the other way around
404    // need not be the case.
405    public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
406
407    /** Control over CPU and battery monitoring */
408    // write battery stats every 30 minutes.
409    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
410    static final boolean MONITOR_CPU_USAGE = true;
411    // don't sample cpu less than every 5 seconds.
412    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
413    // wait possibly forever for next cpu sample.
414    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
415    static final boolean MONITOR_THREAD_CPU_USAGE = false;
416
417    // The flags that are set for all calls we make to the package manager.
418    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
419
420    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
421
422    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
423
424    // Amount of time after a call to stopAppSwitches() during which we will
425    // prevent further untrusted switches from happening.
426    static final long APP_SWITCH_DELAY_TIME = 5*1000;
427
428    // How long we wait for a launched process to attach to the activity manager
429    // before we decide it's never going to come up for real.
430    static final int PROC_START_TIMEOUT = 10*1000;
431    // How long we wait for an attached process to publish its content providers
432    // before we decide it must be hung.
433    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
434
435    // How long we will retain processes hosting content providers in the "last activity"
436    // state before allowing them to drop down to the regular cached LRU list.  This is
437    // to avoid thrashing of provider processes under low memory situations.
438    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
439
440    // How long we wait for a launched process to attach to the activity manager
441    // before we decide it's never going to come up for real, when the process was
442    // started with a wrapper for instrumentation (such as Valgrind) because it
443    // could take much longer than usual.
444    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
445
446    // How long to wait after going idle before forcing apps to GC.
447    static final int GC_TIMEOUT = 5*1000;
448
449    // The minimum amount of time between successive GC requests for a process.
450    static final int GC_MIN_INTERVAL = 60*1000;
451
452    // The minimum amount of time between successive PSS requests for a process.
453    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
454
455    // The minimum amount of time between successive PSS requests for a process
456    // when the request is due to the memory state being lowered.
457    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
458
459    // The rate at which we check for apps using excessive power -- 15 mins.
460    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
461
462    // The minimum sample duration we will allow before deciding we have
463    // enough data on wake locks to start killing things.
464    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
465
466    // The minimum sample duration we will allow before deciding we have
467    // enough data on CPU usage to start killing things.
468    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
469
470    // How long we allow a receiver to run before giving up on it.
471    static final int BROADCAST_FG_TIMEOUT = 10*1000;
472    static final int BROADCAST_BG_TIMEOUT = 60*1000;
473
474    // How long we wait until we timeout on key dispatching.
475    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
476
477    // How long we wait until we timeout on key dispatching during instrumentation.
478    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
479
480    // This is the amount of time an app needs to be running a foreground service before
481    // we will consider it to be doing interaction for usage stats.
482    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
483
484    // Maximum amount of time we will allow to elapse before re-reporting usage stats
485    // interaction with foreground processes.
486    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
487
488    // This is the amount of time we allow an app to settle after it goes into the background,
489    // before we start restricting what it can do.
490    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
491
492    // How long to wait in getAssistContextExtras for the activity and foreground services
493    // to respond with the result.
494    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
495
496    // How long top wait when going through the modern assist (which doesn't need to block
497    // on getting this result before starting to launch its UI).
498    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
499
500    // Maximum number of persisted Uri grants a package is allowed
501    static final int MAX_PERSISTED_URI_GRANTS = 128;
502
503    static final int MY_PID = Process.myPid();
504
505    static final String[] EMPTY_STRING_ARRAY = new String[0];
506
507    // How many bytes to write into the dropbox log before truncating
508    static final int DROPBOX_MAX_SIZE = 192 * 1024;
509    // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
510    // as one line, but close enough for now.
511    static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
512
513    // Access modes for handleIncomingUser.
514    static final int ALLOW_NON_FULL = 0;
515    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
516    static final int ALLOW_FULL_ONLY = 2;
517
518    // Delay in notifying task stack change listeners (in millis)
519    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
520
521    // Necessary ApplicationInfo flags to mark an app as persistent
522    private static final int PERSISTENT_MASK =
523            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
524
525    // Intent sent when remote bugreport collection has been completed
526    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
527            "android.intent.action.REMOTE_BUGREPORT_FINISHED";
528
529    // Delay to disable app launch boost
530    static final int APP_BOOST_MESSAGE_DELAY = 3000;
531    // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
532    static final int APP_BOOST_TIMEOUT = 2500;
533
534    // Used to indicate that a task is removed it should also be removed from recents.
535    private static final boolean REMOVE_FROM_RECENTS = true;
536    // Used to indicate that an app transition should be animated.
537    static final boolean ANIMATE = true;
538
539    // Determines whether to take full screen screenshots
540    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
541    public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
542
543    private static native int nativeMigrateToBoost();
544    private static native int nativeMigrateFromBoost();
545    private boolean mIsBoosted = false;
546    private long mBoostStartTime = 0;
547
548    /** All system services */
549    SystemServiceManager mSystemServiceManager;
550
551    private Installer mInstaller;
552
553    /** Run all ActivityStacks through this */
554    final ActivityStackSupervisor mStackSupervisor;
555
556    final ActivityStarter mActivityStarter;
557
558    /** Task stack change listeners. */
559    private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
560            new RemoteCallbackList<ITaskStackListener>();
561
562    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
563
564    public IntentFirewall mIntentFirewall;
565
566    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
567    // default actuion automatically.  Important for devices without direct input
568    // devices.
569    private boolean mShowDialogs = true;
570    private boolean mInVrMode = false;
571
572    // Whether we should use SCHED_FIFO for UI and RenderThreads.
573    private boolean mUseFifoUiScheduling = false;
574
575    BroadcastQueue mFgBroadcastQueue;
576    BroadcastQueue mBgBroadcastQueue;
577    // Convenient for easy iteration over the queues. Foreground is first
578    // so that dispatch of foreground broadcasts gets precedence.
579    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
580
581    BroadcastStats mLastBroadcastStats;
582    BroadcastStats mCurBroadcastStats;
583
584    BroadcastQueue broadcastQueueForIntent(Intent intent) {
585        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
586        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
587                "Broadcast intent " + intent + " on "
588                + (isFg ? "foreground" : "background") + " queue");
589        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
590    }
591
592    /**
593     * Activity we have told the window manager to have key focus.
594     */
595    ActivityRecord mFocusedActivity = null;
596
597    /**
598     * User id of the last activity mFocusedActivity was set to.
599     */
600    private int mLastFocusedUserId;
601
602    /**
603     * If non-null, we are tracking the time the user spends in the currently focused app.
604     */
605    private AppTimeTracker mCurAppTimeTracker;
606
607    /**
608     * List of intents that were used to start the most recent tasks.
609     */
610    final RecentTasks mRecentTasks;
611
612    /**
613     * For addAppTask: cached of the last activity component that was added.
614     */
615    ComponentName mLastAddedTaskComponent;
616
617    /**
618     * For addAppTask: cached of the last activity uid that was added.
619     */
620    int mLastAddedTaskUid;
621
622    /**
623     * For addAppTask: cached of the last ActivityInfo that was added.
624     */
625    ActivityInfo mLastAddedTaskActivity;
626
627    /**
628     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
629     */
630    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
631
632    /**
633     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
634     */
635    String mDeviceOwnerName;
636
637    final UserController mUserController;
638
639    final AppErrors mAppErrors;
640
641    boolean mDoingSetFocusedActivity;
642
643    public boolean canShowErrorDialogs() {
644        return mShowDialogs && !mSleeping && !mShuttingDown
645                && mLockScreenShown != LOCK_SCREEN_SHOWN;
646    }
647
648    private static final class PriorityState {
649        // Acts as counter for number of synchronized region that needs to acquire 'this' as a lock
650        // the current thread is currently in. When it drops down to zero, we will no longer boost
651        // the thread's priority.
652        private int regionCounter = 0;
653
654        // The thread's previous priority before boosting.
655        private int prevPriority = Integer.MIN_VALUE;
656    }
657
658    static ThreadLocal<PriorityState> sThreadPriorityState = new ThreadLocal<PriorityState>() {
659        @Override protected PriorityState initialValue() {
660            return new PriorityState();
661        }
662    };
663
664    static void boostPriorityForLockedSection() {
665        int tid = Process.myTid();
666        int prevPriority = Process.getThreadPriority(tid);
667        PriorityState state = sThreadPriorityState.get();
668        if (state.regionCounter == 0 && prevPriority > -2) {
669            state.prevPriority = prevPriority;
670            Process.setThreadPriority(tid, -2);
671        }
672        state.regionCounter++;
673    }
674
675    static void resetPriorityAfterLockedSection() {
676        PriorityState state = sThreadPriorityState.get();
677        state.regionCounter--;
678        if (state.regionCounter == 0 && state.prevPriority > -2) {
679            Process.setThreadPriority(Process.myTid(), state.prevPriority);
680        }
681    }
682
683    public class PendingAssistExtras extends Binder implements Runnable {
684        public final ActivityRecord activity;
685        public final Bundle extras;
686        public final Intent intent;
687        public final String hint;
688        public final IResultReceiver receiver;
689        public final int userHandle;
690        public boolean haveResult = false;
691        public Bundle result = null;
692        public AssistStructure structure = null;
693        public AssistContent content = null;
694        public Bundle receiverExtras;
695
696        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
697                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
698            activity = _activity;
699            extras = _extras;
700            intent = _intent;
701            hint = _hint;
702            receiver = _receiver;
703            receiverExtras = _receiverExtras;
704            userHandle = _userHandle;
705        }
706        @Override
707        public void run() {
708            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
709            synchronized (this) {
710                haveResult = true;
711                notifyAll();
712            }
713            pendingAssistExtrasTimedOut(this);
714        }
715    }
716
717    final ArrayList<PendingAssistExtras> mPendingAssistExtras
718            = new ArrayList<PendingAssistExtras>();
719
720    /**
721     * Process management.
722     */
723    final ProcessList mProcessList = new ProcessList();
724
725    /**
726     * All of the applications we currently have running organized by name.
727     * The keys are strings of the application package name (as
728     * returned by the package manager), and the keys are ApplicationRecord
729     * objects.
730     */
731    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
732
733    /**
734     * Tracking long-term execution of processes to look for abuse and other
735     * bad app behavior.
736     */
737    final ProcessStatsService mProcessStats;
738
739    /**
740     * The currently running isolated processes.
741     */
742    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
743
744    /**
745     * Counter for assigning isolated process uids, to avoid frequently reusing the
746     * same ones.
747     */
748    int mNextIsolatedProcessUid = 0;
749
750    /**
751     * The currently running heavy-weight process, if any.
752     */
753    ProcessRecord mHeavyWeightProcess = null;
754
755    /**
756     * All of the processes we currently have running organized by pid.
757     * The keys are the pid running the application.
758     *
759     * <p>NOTE: This object is protected by its own lock, NOT the global
760     * activity manager lock!
761     */
762    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
763
764    /**
765     * All of the processes that have been forced to be foreground.  The key
766     * is the pid of the caller who requested it (we hold a death
767     * link on it).
768     */
769    abstract class ForegroundToken implements IBinder.DeathRecipient {
770        int pid;
771        IBinder token;
772    }
773    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
774
775    /**
776     * List of records for processes that someone had tried to start before the
777     * system was ready.  We don't start them at that point, but ensure they
778     * are started by the time booting is complete.
779     */
780    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
781
782    /**
783     * List of persistent applications that are in the process
784     * of being started.
785     */
786    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
787
788    /**
789     * Processes that are being forcibly torn down.
790     */
791    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
792
793    /**
794     * List of running applications, sorted by recent usage.
795     * The first entry in the list is the least recently used.
796     */
797    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
798
799    /**
800     * Where in mLruProcesses that the processes hosting activities start.
801     */
802    int mLruProcessActivityStart = 0;
803
804    /**
805     * Where in mLruProcesses that the processes hosting services start.
806     * This is after (lower index) than mLruProcessesActivityStart.
807     */
808    int mLruProcessServiceStart = 0;
809
810    /**
811     * List of processes that should gc as soon as things are idle.
812     */
813    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
814
815    /**
816     * Processes we want to collect PSS data from.
817     */
818    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
819
820    private boolean mBinderTransactionTrackingEnabled = false;
821
822    /**
823     * Last time we requested PSS data of all processes.
824     */
825    long mLastFullPssTime = SystemClock.uptimeMillis();
826
827    /**
828     * If set, the next time we collect PSS data we should do a full collection
829     * with data from native processes and the kernel.
830     */
831    boolean mFullPssPending = false;
832
833    /**
834     * This is the process holding what we currently consider to be
835     * the "home" activity.
836     */
837    ProcessRecord mHomeProcess;
838
839    /**
840     * This is the process holding the activity the user last visited that
841     * is in a different process from the one they are currently in.
842     */
843    ProcessRecord mPreviousProcess;
844
845    /**
846     * The time at which the previous process was last visible.
847     */
848    long mPreviousProcessVisibleTime;
849
850    /**
851     * Track all uids that have actively running processes.
852     */
853    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
854
855    /**
856     * This is for verifying the UID report flow.
857     */
858    static final boolean VALIDATE_UID_STATES = true;
859    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
860
861    /**
862     * Packages that the user has asked to have run in screen size
863     * compatibility mode instead of filling the screen.
864     */
865    final CompatModePackages mCompatModePackages;
866
867    /**
868     * Set of IntentSenderRecord objects that are currently active.
869     */
870    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
871            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
872
873    /**
874     * Fingerprints (hashCode()) of stack traces that we've
875     * already logged DropBox entries for.  Guarded by itself.  If
876     * something (rogue user app) forces this over
877     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
878     */
879    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
880    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
881
882    /**
883     * Strict Mode background batched logging state.
884     *
885     * The string buffer is guarded by itself, and its lock is also
886     * used to determine if another batched write is already
887     * in-flight.
888     */
889    private final StringBuilder mStrictModeBuffer = new StringBuilder();
890
891    /**
892     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
893     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
894     */
895    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
896
897    /**
898     * Resolver for broadcast intents to registered receivers.
899     * Holds BroadcastFilter (subclass of IntentFilter).
900     */
901    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
902            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
903        @Override
904        protected boolean allowFilterResult(
905                BroadcastFilter filter, List<BroadcastFilter> dest) {
906            IBinder target = filter.receiverList.receiver.asBinder();
907            for (int i = dest.size() - 1; i >= 0; i--) {
908                if (dest.get(i).receiverList.receiver.asBinder() == target) {
909                    return false;
910                }
911            }
912            return true;
913        }
914
915        @Override
916        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
917            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
918                    || userId == filter.owningUserId) {
919                return super.newResult(filter, match, userId);
920            }
921            return null;
922        }
923
924        @Override
925        protected BroadcastFilter[] newArray(int size) {
926            return new BroadcastFilter[size];
927        }
928
929        @Override
930        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
931            return packageName.equals(filter.packageName);
932        }
933    };
934
935    /**
936     * State of all active sticky broadcasts per user.  Keys are the action of the
937     * sticky Intent, values are an ArrayList of all broadcasted intents with
938     * that action (which should usually be one).  The SparseArray is keyed
939     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
940     * for stickies that are sent to all users.
941     */
942    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
943            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
944
945    final ActiveServices mServices;
946
947    final static class Association {
948        final int mSourceUid;
949        final String mSourceProcess;
950        final int mTargetUid;
951        final ComponentName mTargetComponent;
952        final String mTargetProcess;
953
954        int mCount;
955        long mTime;
956
957        int mNesting;
958        long mStartTime;
959
960        // states of the source process when the bind occurred.
961        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
962        long mLastStateUptime;
963        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
964                - ActivityManager.MIN_PROCESS_STATE+1];
965
966        Association(int sourceUid, String sourceProcess, int targetUid,
967                ComponentName targetComponent, String targetProcess) {
968            mSourceUid = sourceUid;
969            mSourceProcess = sourceProcess;
970            mTargetUid = targetUid;
971            mTargetComponent = targetComponent;
972            mTargetProcess = targetProcess;
973        }
974    }
975
976    /**
977     * When service association tracking is enabled, this is all of the associations we
978     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
979     * -> association data.
980     */
981    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
982            mAssociations = new SparseArray<>();
983    boolean mTrackingAssociations;
984
985    /**
986     * Backup/restore process management
987     */
988    String mBackupAppName = null;
989    BackupRecord mBackupTarget = null;
990
991    final ProviderMap mProviderMap;
992
993    /**
994     * List of content providers who have clients waiting for them.  The
995     * application is currently being launched and the provider will be
996     * removed from this list once it is published.
997     */
998    final ArrayList<ContentProviderRecord> mLaunchingProviders
999            = new ArrayList<ContentProviderRecord>();
1000
1001    /**
1002     * File storing persisted {@link #mGrantedUriPermissions}.
1003     */
1004    private final AtomicFile mGrantFile;
1005
1006    /** XML constants used in {@link #mGrantFile} */
1007    private static final String TAG_URI_GRANTS = "uri-grants";
1008    private static final String TAG_URI_GRANT = "uri-grant";
1009    private static final String ATTR_USER_HANDLE = "userHandle";
1010    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
1011    private static final String ATTR_TARGET_USER_ID = "targetUserId";
1012    private static final String ATTR_SOURCE_PKG = "sourcePkg";
1013    private static final String ATTR_TARGET_PKG = "targetPkg";
1014    private static final String ATTR_URI = "uri";
1015    private static final String ATTR_MODE_FLAGS = "modeFlags";
1016    private static final String ATTR_CREATED_TIME = "createdTime";
1017    private static final String ATTR_PREFIX = "prefix";
1018
1019    /**
1020     * Global set of specific {@link Uri} permissions that have been granted.
1021     * This optimized lookup structure maps from {@link UriPermission#targetUid}
1022     * to {@link UriPermission#uri} to {@link UriPermission}.
1023     */
1024    @GuardedBy("this")
1025    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1026            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1027
1028    public static class GrantUri {
1029        public final int sourceUserId;
1030        public final Uri uri;
1031        public boolean prefix;
1032
1033        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1034            this.sourceUserId = sourceUserId;
1035            this.uri = uri;
1036            this.prefix = prefix;
1037        }
1038
1039        @Override
1040        public int hashCode() {
1041            int hashCode = 1;
1042            hashCode = 31 * hashCode + sourceUserId;
1043            hashCode = 31 * hashCode + uri.hashCode();
1044            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1045            return hashCode;
1046        }
1047
1048        @Override
1049        public boolean equals(Object o) {
1050            if (o instanceof GrantUri) {
1051                GrantUri other = (GrantUri) o;
1052                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1053                        && prefix == other.prefix;
1054            }
1055            return false;
1056        }
1057
1058        @Override
1059        public String toString() {
1060            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1061            if (prefix) result += " [prefix]";
1062            return result;
1063        }
1064
1065        public String toSafeString() {
1066            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1067            if (prefix) result += " [prefix]";
1068            return result;
1069        }
1070
1071        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1072            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1073                    ContentProvider.getUriWithoutUserId(uri), false);
1074        }
1075    }
1076
1077    CoreSettingsObserver mCoreSettingsObserver;
1078
1079    FontScaleSettingObserver mFontScaleSettingObserver;
1080
1081    private final class FontScaleSettingObserver extends ContentObserver {
1082        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1083
1084        public FontScaleSettingObserver() {
1085            super(mHandler);
1086            ContentResolver resolver = mContext.getContentResolver();
1087            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1088        }
1089
1090        @Override
1091        public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1092            if (mFontScaleUri.equals(uri)) {
1093                updateFontScaleIfNeeded(userId);
1094            }
1095        }
1096    }
1097
1098    /**
1099     * Thread-local storage used to carry caller permissions over through
1100     * indirect content-provider access.
1101     */
1102    private class Identity {
1103        public final IBinder token;
1104        public final int pid;
1105        public final int uid;
1106
1107        Identity(IBinder _token, int _pid, int _uid) {
1108            token = _token;
1109            pid = _pid;
1110            uid = _uid;
1111        }
1112    }
1113
1114    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1115
1116    /**
1117     * All information we have collected about the runtime performance of
1118     * any user id that can impact battery performance.
1119     */
1120    final BatteryStatsService mBatteryStatsService;
1121
1122    /**
1123     * Information about component usage
1124     */
1125    UsageStatsManagerInternal mUsageStatsService;
1126
1127    /**
1128     * Access to DeviceIdleController service.
1129     */
1130    DeviceIdleController.LocalService mLocalDeviceIdleController;
1131
1132    /**
1133     * Information about and control over application operations
1134     */
1135    final AppOpsService mAppOpsService;
1136
1137    /**
1138     * Current configuration information.  HistoryRecord objects are given
1139     * a reference to this object to indicate which configuration they are
1140     * currently running in, so this object must be kept immutable.
1141     */
1142    Configuration mConfiguration = new Configuration();
1143
1144    /**
1145     * Current sequencing integer of the configuration, for skipping old
1146     * configurations.
1147     */
1148    int mConfigurationSeq = 0;
1149
1150    boolean mSuppressResizeConfigChanges = false;
1151
1152    /**
1153     * Hardware-reported OpenGLES version.
1154     */
1155    final int GL_ES_VERSION;
1156
1157    /**
1158     * List of initialization arguments to pass to all processes when binding applications to them.
1159     * For example, references to the commonly used services.
1160     */
1161    HashMap<String, IBinder> mAppBindArgs;
1162    HashMap<String, IBinder> mIsolatedAppBindArgs;
1163
1164    /**
1165     * Temporary to avoid allocations.  Protected by main lock.
1166     */
1167    final StringBuilder mStringBuilder = new StringBuilder(256);
1168
1169    /**
1170     * Used to control how we initialize the service.
1171     */
1172    ComponentName mTopComponent;
1173    String mTopAction = Intent.ACTION_MAIN;
1174    String mTopData;
1175
1176    volatile boolean mProcessesReady = false;
1177    volatile boolean mSystemReady = false;
1178    volatile boolean mOnBattery = false;
1179    volatile int mFactoryTest;
1180
1181    @GuardedBy("this") boolean mBooting = false;
1182    @GuardedBy("this") boolean mCallFinishBooting = false;
1183    @GuardedBy("this") boolean mBootAnimationComplete = false;
1184    @GuardedBy("this") boolean mLaunchWarningShown = false;
1185    @GuardedBy("this") boolean mCheckedForSetup = false;
1186
1187    Context mContext;
1188
1189    /**
1190     * The time at which we will allow normal application switches again,
1191     * after a call to {@link #stopAppSwitches()}.
1192     */
1193    long mAppSwitchesAllowedTime;
1194
1195    /**
1196     * This is set to true after the first switch after mAppSwitchesAllowedTime
1197     * is set; any switches after that will clear the time.
1198     */
1199    boolean mDidAppSwitch;
1200
1201    /**
1202     * Last time (in realtime) at which we checked for power usage.
1203     */
1204    long mLastPowerCheckRealtime;
1205
1206    /**
1207     * Last time (in uptime) at which we checked for power usage.
1208     */
1209    long mLastPowerCheckUptime;
1210
1211    /**
1212     * Set while we are wanting to sleep, to prevent any
1213     * activities from being started/resumed.
1214     */
1215    private boolean mSleeping = false;
1216
1217    /**
1218     * The process state used for processes that are running the top activities.
1219     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1220     */
1221    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1222
1223    /**
1224     * Set while we are running a voice interaction.  This overrides
1225     * sleeping while it is active.
1226     */
1227    private IVoiceInteractionSession mRunningVoice;
1228
1229    /**
1230     * For some direct access we need to power manager.
1231     */
1232    PowerManagerInternal mLocalPowerManager;
1233
1234    /**
1235     * We want to hold a wake lock while running a voice interaction session, since
1236     * this may happen with the screen off and we need to keep the CPU running to
1237     * be able to continue to interact with the user.
1238     */
1239    PowerManager.WakeLock mVoiceWakeLock;
1240
1241    /**
1242     * State of external calls telling us if the device is awake or asleep.
1243     */
1244    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1245
1246    /**
1247     * A list of tokens that cause the top activity to be put to sleep.
1248     * They are used by components that may hide and block interaction with underlying
1249     * activities.
1250     */
1251    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1252
1253    static final int LOCK_SCREEN_HIDDEN = 0;
1254    static final int LOCK_SCREEN_LEAVING = 1;
1255    static final int LOCK_SCREEN_SHOWN = 2;
1256    /**
1257     * State of external call telling us if the lock screen is shown.
1258     */
1259    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1260
1261    /**
1262     * Set if we are shutting down the system, similar to sleeping.
1263     */
1264    boolean mShuttingDown = false;
1265
1266    /**
1267     * Current sequence id for oom_adj computation traversal.
1268     */
1269    int mAdjSeq = 0;
1270
1271    /**
1272     * Current sequence id for process LRU updating.
1273     */
1274    int mLruSeq = 0;
1275
1276    /**
1277     * Keep track of the non-cached/empty process we last found, to help
1278     * determine how to distribute cached/empty processes next time.
1279     */
1280    int mNumNonCachedProcs = 0;
1281
1282    /**
1283     * Keep track of the number of cached hidden procs, to balance oom adj
1284     * distribution between those and empty procs.
1285     */
1286    int mNumCachedHiddenProcs = 0;
1287
1288    /**
1289     * Keep track of the number of service processes we last found, to
1290     * determine on the next iteration which should be B services.
1291     */
1292    int mNumServiceProcs = 0;
1293    int mNewNumAServiceProcs = 0;
1294    int mNewNumServiceProcs = 0;
1295
1296    /**
1297     * Allow the current computed overall memory level of the system to go down?
1298     * This is set to false when we are killing processes for reasons other than
1299     * memory management, so that the now smaller process list will not be taken as
1300     * an indication that memory is tighter.
1301     */
1302    boolean mAllowLowerMemLevel = false;
1303
1304    /**
1305     * The last computed memory level, for holding when we are in a state that
1306     * processes are going away for other reasons.
1307     */
1308    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1309
1310    /**
1311     * The last total number of process we have, to determine if changes actually look
1312     * like a shrinking number of process due to lower RAM.
1313     */
1314    int mLastNumProcesses;
1315
1316    /**
1317     * The uptime of the last time we performed idle maintenance.
1318     */
1319    long mLastIdleTime = SystemClock.uptimeMillis();
1320
1321    /**
1322     * Total time spent with RAM that has been added in the past since the last idle time.
1323     */
1324    long mLowRamTimeSinceLastIdle = 0;
1325
1326    /**
1327     * If RAM is currently low, when that horrible situation started.
1328     */
1329    long mLowRamStartTime = 0;
1330
1331    /**
1332     * For reporting to battery stats the current top application.
1333     */
1334    private String mCurResumedPackage = null;
1335    private int mCurResumedUid = -1;
1336
1337    /**
1338     * For reporting to battery stats the apps currently running foreground
1339     * service.  The ProcessMap is package/uid tuples; each of these contain
1340     * an array of the currently foreground processes.
1341     */
1342    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1343            = new ProcessMap<ArrayList<ProcessRecord>>();
1344
1345    /**
1346     * This is set if we had to do a delayed dexopt of an app before launching
1347     * it, to increase the ANR timeouts in that case.
1348     */
1349    boolean mDidDexOpt;
1350
1351    /**
1352     * Set if the systemServer made a call to enterSafeMode.
1353     */
1354    boolean mSafeMode;
1355
1356    /**
1357     * If true, we are running under a test environment so will sample PSS from processes
1358     * much more rapidly to try to collect better data when the tests are rapidly
1359     * running through apps.
1360     */
1361    boolean mTestPssMode = false;
1362
1363    String mDebugApp = null;
1364    boolean mWaitForDebugger = false;
1365    boolean mDebugTransient = false;
1366    String mOrigDebugApp = null;
1367    boolean mOrigWaitForDebugger = false;
1368    boolean mAlwaysFinishActivities = false;
1369    boolean mLenientBackgroundCheck = false;
1370    boolean mForceResizableActivities;
1371    boolean mSupportsMultiWindow;
1372    boolean mSupportsFreeformWindowManagement;
1373    boolean mSupportsPictureInPicture;
1374    boolean mSupportsLeanbackOnly;
1375    Rect mDefaultPinnedStackBounds;
1376    IActivityController mController = null;
1377    boolean mControllerIsAMonkey = false;
1378    String mProfileApp = null;
1379    ProcessRecord mProfileProc = null;
1380    String mProfileFile;
1381    ParcelFileDescriptor mProfileFd;
1382    int mSamplingInterval = 0;
1383    boolean mAutoStopProfiler = false;
1384    boolean mStreamingOutput = 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 boolean mPermissionReviewRequired;
1580
1581    final class KillHandler extends Handler {
1582        static final int KILL_PROCESS_GROUP_MSG = 4000;
1583
1584        public KillHandler(Looper looper) {
1585            super(looper, null, true);
1586        }
1587
1588        @Override
1589        public void handleMessage(Message msg) {
1590            switch (msg.what) {
1591                case KILL_PROCESS_GROUP_MSG:
1592                {
1593                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1594                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1595                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1596                }
1597                break;
1598
1599                default:
1600                    super.handleMessage(msg);
1601            }
1602        }
1603    }
1604
1605    final class UiHandler extends Handler {
1606        public UiHandler() {
1607            super(com.android.server.UiThread.get().getLooper(), null, true);
1608        }
1609
1610        @Override
1611        public void handleMessage(Message msg) {
1612            switch (msg.what) {
1613            case SHOW_ERROR_UI_MSG: {
1614                mAppErrors.handleShowAppErrorUi(msg);
1615                ensureBootCompleted();
1616            } break;
1617            case SHOW_NOT_RESPONDING_UI_MSG: {
1618                mAppErrors.handleShowAnrUi(msg);
1619                ensureBootCompleted();
1620            } break;
1621            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1622                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1623                synchronized (ActivityManagerService.this) {
1624                    ProcessRecord proc = (ProcessRecord) data.get("app");
1625                    if (proc == null) {
1626                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1627                        break;
1628                    }
1629                    if (proc.crashDialog != null) {
1630                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1631                        return;
1632                    }
1633                    AppErrorResult res = (AppErrorResult) data.get("result");
1634                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1635                        Dialog d = new StrictModeViolationDialog(mContext,
1636                                ActivityManagerService.this, res, proc);
1637                        d.show();
1638                        proc.crashDialog = d;
1639                    } else {
1640                        // The device is asleep, so just pretend that the user
1641                        // saw a crash dialog and hit "force quit".
1642                        res.set(0);
1643                    }
1644                }
1645                ensureBootCompleted();
1646            } break;
1647            case SHOW_FACTORY_ERROR_UI_MSG: {
1648                Dialog d = new FactoryErrorDialog(
1649                    mContext, msg.getData().getCharSequence("msg"));
1650                d.show();
1651                ensureBootCompleted();
1652            } break;
1653            case WAIT_FOR_DEBUGGER_UI_MSG: {
1654                synchronized (ActivityManagerService.this) {
1655                    ProcessRecord app = (ProcessRecord)msg.obj;
1656                    if (msg.arg1 != 0) {
1657                        if (!app.waitedForDebugger) {
1658                            Dialog d = new AppWaitingForDebuggerDialog(
1659                                    ActivityManagerService.this,
1660                                    mContext, app);
1661                            app.waitDialog = d;
1662                            app.waitedForDebugger = true;
1663                            d.show();
1664                        }
1665                    } else {
1666                        if (app.waitDialog != null) {
1667                            app.waitDialog.dismiss();
1668                            app.waitDialog = null;
1669                        }
1670                    }
1671                }
1672            } break;
1673            case SHOW_UID_ERROR_UI_MSG: {
1674                if (mShowDialogs) {
1675                    AlertDialog d = new BaseErrorDialog(mContext);
1676                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1677                    d.setCancelable(false);
1678                    d.setTitle(mContext.getText(R.string.android_system_label));
1679                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1680                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1681                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1682                    d.show();
1683                }
1684            } break;
1685            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1686                if (mShowDialogs) {
1687                    AlertDialog d = new BaseErrorDialog(mContext);
1688                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1689                    d.setCancelable(false);
1690                    d.setTitle(mContext.getText(R.string.android_system_label));
1691                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1692                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1693                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1694                    d.show();
1695                }
1696            } break;
1697            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1698                synchronized (ActivityManagerService.this) {
1699                    ActivityRecord ar = (ActivityRecord) msg.obj;
1700                    if (mCompatModeDialog != null) {
1701                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1702                                ar.info.applicationInfo.packageName)) {
1703                            return;
1704                        }
1705                        mCompatModeDialog.dismiss();
1706                        mCompatModeDialog = null;
1707                    }
1708                    if (ar != null && false) {
1709                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1710                                ar.packageName)) {
1711                            int mode = mCompatModePackages.computeCompatModeLocked(
1712                                    ar.info.applicationInfo);
1713                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1714                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1715                                mCompatModeDialog = new CompatModeDialog(
1716                                        ActivityManagerService.this, mContext,
1717                                        ar.info.applicationInfo);
1718                                mCompatModeDialog.show();
1719                            }
1720                        }
1721                    }
1722                }
1723                break;
1724            }
1725            case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1726                synchronized (ActivityManagerService.this) {
1727                    final ActivityRecord ar = (ActivityRecord) msg.obj;
1728                    if (mUnsupportedDisplaySizeDialog != null) {
1729                        mUnsupportedDisplaySizeDialog.dismiss();
1730                        mUnsupportedDisplaySizeDialog = null;
1731                    }
1732                    if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1733                            ar.packageName)) {
1734                        mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1735                                ActivityManagerService.this, mContext, ar.info.applicationInfo);
1736                        mUnsupportedDisplaySizeDialog.show();
1737                    }
1738                }
1739                break;
1740            }
1741            case START_USER_SWITCH_UI_MSG: {
1742                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1743                break;
1744            }
1745            case DISMISS_DIALOG_UI_MSG: {
1746                final Dialog d = (Dialog) msg.obj;
1747                d.dismiss();
1748                break;
1749            }
1750            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1751                dispatchProcessesChanged();
1752                break;
1753            }
1754            case DISPATCH_PROCESS_DIED_UI_MSG: {
1755                final int pid = msg.arg1;
1756                final int uid = msg.arg2;
1757                dispatchProcessDied(pid, uid);
1758                break;
1759            }
1760            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1761                dispatchUidsChanged();
1762            } break;
1763            }
1764        }
1765    }
1766
1767    final class MainHandler extends Handler {
1768        public MainHandler(Looper looper) {
1769            super(looper, null, true);
1770        }
1771
1772        @Override
1773        public void handleMessage(Message msg) {
1774            switch (msg.what) {
1775            case UPDATE_CONFIGURATION_MSG: {
1776                final ContentResolver resolver = mContext.getContentResolver();
1777                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1778                        msg.arg1);
1779            } break;
1780            case GC_BACKGROUND_PROCESSES_MSG: {
1781                synchronized (ActivityManagerService.this) {
1782                    performAppGcsIfAppropriateLocked();
1783                }
1784            } break;
1785            case SERVICE_TIMEOUT_MSG: {
1786                if (mDidDexOpt) {
1787                    mDidDexOpt = false;
1788                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1789                    nmsg.obj = msg.obj;
1790                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1791                    return;
1792                }
1793                mServices.serviceTimeout((ProcessRecord)msg.obj);
1794            } break;
1795            case UPDATE_TIME_ZONE: {
1796                synchronized (ActivityManagerService.this) {
1797                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1798                        ProcessRecord r = mLruProcesses.get(i);
1799                        if (r.thread != null) {
1800                            try {
1801                                r.thread.updateTimeZone();
1802                            } catch (RemoteException ex) {
1803                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1804                            }
1805                        }
1806                    }
1807                }
1808            } break;
1809            case CLEAR_DNS_CACHE_MSG: {
1810                synchronized (ActivityManagerService.this) {
1811                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1812                        ProcessRecord r = mLruProcesses.get(i);
1813                        if (r.thread != null) {
1814                            try {
1815                                r.thread.clearDnsCache();
1816                            } catch (RemoteException ex) {
1817                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1818                            }
1819                        }
1820                    }
1821                }
1822            } break;
1823            case UPDATE_HTTP_PROXY_MSG: {
1824                ProxyInfo proxy = (ProxyInfo)msg.obj;
1825                String host = "";
1826                String port = "";
1827                String exclList = "";
1828                Uri pacFileUrl = Uri.EMPTY;
1829                if (proxy != null) {
1830                    host = proxy.getHost();
1831                    port = Integer.toString(proxy.getPort());
1832                    exclList = proxy.getExclusionListAsString();
1833                    pacFileUrl = proxy.getPacFileUrl();
1834                }
1835                synchronized (ActivityManagerService.this) {
1836                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1837                        ProcessRecord r = mLruProcesses.get(i);
1838                        if (r.thread != null) {
1839                            try {
1840                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1841                            } catch (RemoteException ex) {
1842                                Slog.w(TAG, "Failed to update http proxy for: " +
1843                                        r.info.processName);
1844                            }
1845                        }
1846                    }
1847                }
1848            } break;
1849            case PROC_START_TIMEOUT_MSG: {
1850                if (mDidDexOpt) {
1851                    mDidDexOpt = false;
1852                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1853                    nmsg.obj = msg.obj;
1854                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1855                    return;
1856                }
1857                ProcessRecord app = (ProcessRecord)msg.obj;
1858                synchronized (ActivityManagerService.this) {
1859                    processStartTimedOutLocked(app);
1860                }
1861            } break;
1862            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1863                ProcessRecord app = (ProcessRecord)msg.obj;
1864                synchronized (ActivityManagerService.this) {
1865                    processContentProviderPublishTimedOutLocked(app);
1866                }
1867            } break;
1868            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1869                synchronized (ActivityManagerService.this) {
1870                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1871                }
1872            } break;
1873            case KILL_APPLICATION_MSG: {
1874                synchronized (ActivityManagerService.this) {
1875                    final int appId = msg.arg1;
1876                    final int userId = msg.arg2;
1877                    Bundle bundle = (Bundle)msg.obj;
1878                    String pkg = bundle.getString("pkg");
1879                    String reason = bundle.getString("reason");
1880                    forceStopPackageLocked(pkg, appId, false, false, true, false,
1881                            false, userId, reason);
1882                }
1883            } break;
1884            case FINALIZE_PENDING_INTENT_MSG: {
1885                ((PendingIntentRecord)msg.obj).completeFinalize();
1886            } break;
1887            case POST_HEAVY_NOTIFICATION_MSG: {
1888                INotificationManager inm = NotificationManager.getService();
1889                if (inm == null) {
1890                    return;
1891                }
1892
1893                ActivityRecord root = (ActivityRecord)msg.obj;
1894                ProcessRecord process = root.app;
1895                if (process == null) {
1896                    return;
1897                }
1898
1899                try {
1900                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1901                    String text = mContext.getString(R.string.heavy_weight_notification,
1902                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1903                    Notification notification = new Notification.Builder(context)
1904                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1905                            .setWhen(0)
1906                            .setOngoing(true)
1907                            .setTicker(text)
1908                            .setColor(mContext.getColor(
1909                                    com.android.internal.R.color.system_notification_accent_color))
1910                            .setContentTitle(text)
1911                            .setContentText(
1912                                    mContext.getText(R.string.heavy_weight_notification_detail))
1913                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1914                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1915                                    new UserHandle(root.userId)))
1916                            .build();
1917                    try {
1918                        int[] outId = new int[1];
1919                        inm.enqueueNotificationWithTag("android", "android", null,
1920                                R.string.heavy_weight_notification,
1921                                notification, outId, root.userId);
1922                    } catch (RuntimeException e) {
1923                        Slog.w(ActivityManagerService.TAG,
1924                                "Error showing notification for heavy-weight app", e);
1925                    } catch (RemoteException e) {
1926                    }
1927                } catch (NameNotFoundException e) {
1928                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1929                }
1930            } break;
1931            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1932                INotificationManager inm = NotificationManager.getService();
1933                if (inm == null) {
1934                    return;
1935                }
1936                try {
1937                    inm.cancelNotificationWithTag("android", null,
1938                            R.string.heavy_weight_notification,  msg.arg1);
1939                } catch (RuntimeException e) {
1940                    Slog.w(ActivityManagerService.TAG,
1941                            "Error canceling notification for service", e);
1942                } catch (RemoteException e) {
1943                }
1944            } break;
1945            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1946                synchronized (ActivityManagerService.this) {
1947                    checkExcessivePowerUsageLocked(true);
1948                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1949                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1950                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1951                }
1952            } break;
1953            case REPORT_MEM_USAGE_MSG: {
1954                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1955                Thread thread = new Thread() {
1956                    @Override public void run() {
1957                        reportMemUsage(memInfos);
1958                    }
1959                };
1960                thread.start();
1961                break;
1962            }
1963            case REPORT_USER_SWITCH_MSG: {
1964                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1965                break;
1966            }
1967            case CONTINUE_USER_SWITCH_MSG: {
1968                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1969                break;
1970            }
1971            case USER_SWITCH_TIMEOUT_MSG: {
1972                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1973                break;
1974            }
1975            case IMMERSIVE_MODE_LOCK_MSG: {
1976                final boolean nextState = (msg.arg1 != 0);
1977                if (mUpdateLock.isHeld() != nextState) {
1978                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1979                            "Applying new update lock state '" + nextState
1980                            + "' for " + (ActivityRecord)msg.obj);
1981                    if (nextState) {
1982                        mUpdateLock.acquire();
1983                    } else {
1984                        mUpdateLock.release();
1985                    }
1986                }
1987                break;
1988            }
1989            case PERSIST_URI_GRANTS_MSG: {
1990                writeGrantedUriPermissions();
1991                break;
1992            }
1993            case REQUEST_ALL_PSS_MSG: {
1994                synchronized (ActivityManagerService.this) {
1995                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1996                }
1997                break;
1998            }
1999            case START_PROFILES_MSG: {
2000                synchronized (ActivityManagerService.this) {
2001                    mUserController.startProfilesLocked();
2002                }
2003                break;
2004            }
2005            case UPDATE_TIME: {
2006                synchronized (ActivityManagerService.this) {
2007                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2008                        ProcessRecord r = mLruProcesses.get(i);
2009                        if (r.thread != null) {
2010                            try {
2011                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
2012                            } catch (RemoteException ex) {
2013                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
2014                            }
2015                        }
2016                    }
2017                }
2018                break;
2019            }
2020            case SYSTEM_USER_START_MSG: {
2021                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2022                        Integer.toString(msg.arg1), msg.arg1);
2023                mSystemServiceManager.startUser(msg.arg1);
2024                break;
2025            }
2026            case SYSTEM_USER_UNLOCK_MSG: {
2027                final int userId = msg.arg1;
2028                mSystemServiceManager.unlockUser(userId);
2029                synchronized (ActivityManagerService.this) {
2030                    mRecentTasks.loadUserRecentsLocked(userId);
2031                }
2032                if (userId == UserHandle.USER_SYSTEM) {
2033                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2034                }
2035                installEncryptionUnawareProviders(userId);
2036                mUserController.finishUserUnlocked((UserState) msg.obj);
2037                break;
2038            }
2039            case SYSTEM_USER_CURRENT_MSG: {
2040                mBatteryStatsService.noteEvent(
2041                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2042                        Integer.toString(msg.arg2), msg.arg2);
2043                mBatteryStatsService.noteEvent(
2044                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2045                        Integer.toString(msg.arg1), msg.arg1);
2046                mSystemServiceManager.switchUser(msg.arg1);
2047                break;
2048            }
2049            case ENTER_ANIMATION_COMPLETE_MSG: {
2050                synchronized (ActivityManagerService.this) {
2051                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2052                    if (r != null && r.app != null && r.app.thread != null) {
2053                        try {
2054                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2055                        } catch (RemoteException e) {
2056                        }
2057                    }
2058                }
2059                break;
2060            }
2061            case FINISH_BOOTING_MSG: {
2062                if (msg.arg1 != 0) {
2063                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2064                    finishBooting();
2065                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2066                }
2067                if (msg.arg2 != 0) {
2068                    enableScreenAfterBoot();
2069                }
2070                break;
2071            }
2072            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2073                try {
2074                    Locale l = (Locale) msg.obj;
2075                    IBinder service = ServiceManager.getService("mount");
2076                    IMountService mountService = IMountService.Stub.asInterface(service);
2077                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2078                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2079                } catch (RemoteException e) {
2080                    Log.e(TAG, "Error storing locale for decryption UI", e);
2081                }
2082                break;
2083            }
2084            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
2085                synchronized (ActivityManagerService.this) {
2086                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2087                        try {
2088                            // Make a one-way callback to the listener
2089                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
2090                        } catch (RemoteException e){
2091                            // Handled by the RemoteCallbackList
2092                        }
2093                    }
2094                    mTaskStackListeners.finishBroadcast();
2095                }
2096                break;
2097            }
2098            case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
2099                synchronized (ActivityManagerService.this) {
2100                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2101                        try {
2102                            // Make a one-way callback to the listener
2103                            mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
2104                        } catch (RemoteException e){
2105                            // Handled by the RemoteCallbackList
2106                        }
2107                    }
2108                    mTaskStackListeners.finishBroadcast();
2109                }
2110                break;
2111            }
2112            case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
2113                synchronized (ActivityManagerService.this) {
2114                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2115                        try {
2116                            // Make a one-way callback to the listener
2117                            mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
2118                        } catch (RemoteException e){
2119                            // Handled by the RemoteCallbackList
2120                        }
2121                    }
2122                    mTaskStackListeners.finishBroadcast();
2123                }
2124                break;
2125            }
2126            case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2127                synchronized (ActivityManagerService.this) {
2128                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2129                        try {
2130                            // Make a one-way callback to the listener
2131                            mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2132                        } catch (RemoteException e){
2133                            // Handled by the RemoteCallbackList
2134                        }
2135                    }
2136                    mTaskStackListeners.finishBroadcast();
2137                }
2138                break;
2139            }
2140            case NOTIFY_FORCED_RESIZABLE_MSG: {
2141                synchronized (ActivityManagerService.this) {
2142                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2143                        try {
2144                            // Make a one-way callback to the listener
2145                            mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
2146                                    (String) msg.obj, msg.arg1);
2147                        } catch (RemoteException e){
2148                            // Handled by the RemoteCallbackList
2149                        }
2150                    }
2151                    mTaskStackListeners.finishBroadcast();
2152                }
2153                break;
2154            }
2155                case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
2156                    synchronized (ActivityManagerService.this) {
2157                        for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2158                            try {
2159                                // Make a one-way callback to the listener
2160                                mTaskStackListeners.getBroadcastItem(i)
2161                                        .onActivityDismissingDockedStack();
2162                            } catch (RemoteException e){
2163                                // Handled by the RemoteCallbackList
2164                            }
2165                        }
2166                        mTaskStackListeners.finishBroadcast();
2167                    }
2168                    break;
2169                }
2170            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2171                final int uid = msg.arg1;
2172                final byte[] firstPacket = (byte[]) msg.obj;
2173
2174                synchronized (mPidsSelfLocked) {
2175                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2176                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2177                        if (p.uid == uid) {
2178                            try {
2179                                p.thread.notifyCleartextNetwork(firstPacket);
2180                            } catch (RemoteException ignored) {
2181                            }
2182                        }
2183                    }
2184                }
2185                break;
2186            }
2187            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2188                final String procName;
2189                final int uid;
2190                final long memLimit;
2191                final String reportPackage;
2192                synchronized (ActivityManagerService.this) {
2193                    procName = mMemWatchDumpProcName;
2194                    uid = mMemWatchDumpUid;
2195                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2196                    if (val == null) {
2197                        val = mMemWatchProcesses.get(procName, 0);
2198                    }
2199                    if (val != null) {
2200                        memLimit = val.first;
2201                        reportPackage = val.second;
2202                    } else {
2203                        memLimit = 0;
2204                        reportPackage = null;
2205                    }
2206                }
2207                if (procName == null) {
2208                    return;
2209                }
2210
2211                if (DEBUG_PSS) Slog.d(TAG_PSS,
2212                        "Showing dump heap notification from " + procName + "/" + uid);
2213
2214                INotificationManager inm = NotificationManager.getService();
2215                if (inm == null) {
2216                    return;
2217                }
2218
2219                String text = mContext.getString(R.string.dump_heap_notification, procName);
2220
2221
2222                Intent deleteIntent = new Intent();
2223                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2224                Intent intent = new Intent();
2225                intent.setClassName("android", DumpHeapActivity.class.getName());
2226                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2227                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2228                if (reportPackage != null) {
2229                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2230                }
2231                int userId = UserHandle.getUserId(uid);
2232                Notification notification = new Notification.Builder(mContext)
2233                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2234                        .setWhen(0)
2235                        .setOngoing(true)
2236                        .setAutoCancel(true)
2237                        .setTicker(text)
2238                        .setColor(mContext.getColor(
2239                                com.android.internal.R.color.system_notification_accent_color))
2240                        .setContentTitle(text)
2241                        .setContentText(
2242                                mContext.getText(R.string.dump_heap_notification_detail))
2243                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2244                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2245                                new UserHandle(userId)))
2246                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2247                                deleteIntent, 0, UserHandle.SYSTEM))
2248                        .build();
2249
2250                try {
2251                    int[] outId = new int[1];
2252                    inm.enqueueNotificationWithTag("android", "android", null,
2253                            R.string.dump_heap_notification,
2254                            notification, outId, userId);
2255                } catch (RuntimeException e) {
2256                    Slog.w(ActivityManagerService.TAG,
2257                            "Error showing notification for dump heap", e);
2258                } catch (RemoteException e) {
2259                }
2260            } break;
2261            case DELETE_DUMPHEAP_MSG: {
2262                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2263                        DumpHeapActivity.JAVA_URI,
2264                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2265                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2266                        UserHandle.myUserId());
2267                synchronized (ActivityManagerService.this) {
2268                    mMemWatchDumpFile = null;
2269                    mMemWatchDumpProcName = null;
2270                    mMemWatchDumpPid = -1;
2271                    mMemWatchDumpUid = -1;
2272                }
2273            } break;
2274            case FOREGROUND_PROFILE_CHANGED_MSG: {
2275                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2276            } break;
2277            case REPORT_TIME_TRACKER_MSG: {
2278                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2279                tracker.deliverResult(mContext);
2280            } break;
2281            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2282                mUserController.dispatchUserSwitchComplete(msg.arg1);
2283            } break;
2284            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2285                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2286                try {
2287                    connection.shutdown();
2288                } catch (RemoteException e) {
2289                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2290                }
2291                // Only a UiAutomation can set this flag and now that
2292                // it is finished we make sure it is reset to its default.
2293                mUserIsMonkey = false;
2294            } break;
2295            case APP_BOOST_DEACTIVATE_MSG: {
2296                synchronized(ActivityManagerService.this) {
2297                    if (mIsBoosted) {
2298                        if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2299                            nativeMigrateFromBoost();
2300                            mIsBoosted = false;
2301                            mBoostStartTime = 0;
2302                        } else {
2303                            Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2304                            mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2305                        }
2306                    }
2307                }
2308            } break;
2309            case IDLE_UIDS_MSG: {
2310                idleUids();
2311            } break;
2312            case LOG_STACK_STATE: {
2313                synchronized (ActivityManagerService.this) {
2314                    mStackSupervisor.logStackState();
2315                }
2316            } break;
2317            case VR_MODE_CHANGE_MSG: {
2318                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2319                if (vrService == null) {
2320                    break;
2321                }
2322                final ActivityRecord r = (ActivityRecord) msg.obj;
2323                boolean vrMode;
2324                ComponentName requestedPackage;
2325                ComponentName callingPackage;
2326                int userId;
2327                synchronized (ActivityManagerService.this) {
2328                    vrMode = r.requestedVrComponent != null;
2329                    requestedPackage = r.requestedVrComponent;
2330                    userId = r.userId;
2331                    callingPackage = r.info.getComponentName();
2332                    if (mInVrMode != vrMode) {
2333                        mInVrMode = vrMode;
2334                        mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2335                        if (r.app != null) {
2336                            ProcessRecord proc = r.app;
2337                            if (proc.vrThreadTid > 0) {
2338                                if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
2339                                    try {
2340                                        if (mInVrMode == true) {
2341                                            Process.setThreadScheduler(proc.vrThreadTid,
2342                                                Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
2343                                        } else {
2344                                            Process.setThreadScheduler(proc.vrThreadTid,
2345                                                Process.SCHED_OTHER, 0);
2346                                        }
2347                                    } catch (IllegalArgumentException e) {
2348                                        Slog.w(TAG, "Failed to set scheduling policy, thread does"
2349                                                + " not exist:\n" + e);
2350                                    }
2351                                }
2352                            }
2353                        }
2354                    }
2355                }
2356                vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2357            } break;
2358            case VR_MODE_APPLY_IF_NEEDED_MSG: {
2359                final ActivityRecord r = (ActivityRecord) msg.obj;
2360                final boolean needsVrMode = r != null && r.requestedVrComponent != null;
2361                if (needsVrMode) {
2362                    applyVrMode(msg.arg1 == 1, r.requestedVrComponent, r.userId,
2363                            r.info.getComponentName(), false);
2364                }
2365            } break;
2366            }
2367        }
2368    };
2369
2370    static final int COLLECT_PSS_BG_MSG = 1;
2371
2372    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2373        @Override
2374        public void handleMessage(Message msg) {
2375            switch (msg.what) {
2376            case COLLECT_PSS_BG_MSG: {
2377                long start = SystemClock.uptimeMillis();
2378                MemInfoReader memInfo = null;
2379                synchronized (ActivityManagerService.this) {
2380                    if (mFullPssPending) {
2381                        mFullPssPending = false;
2382                        memInfo = new MemInfoReader();
2383                    }
2384                }
2385                if (memInfo != null) {
2386                    updateCpuStatsNow();
2387                    long nativeTotalPss = 0;
2388                    final List<ProcessCpuTracker.Stats> stats;
2389                    synchronized (mProcessCpuTracker) {
2390                        stats = mProcessCpuTracker.getStats( (st)-> {
2391                            return st.vsize > 0 && st.uid < Process.FIRST_APPLICATION_UID;
2392                        });
2393                    }
2394                    final int N = stats.size();
2395                    for (int j = 0; j < N; j++) {
2396                        synchronized (mPidsSelfLocked) {
2397                            if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
2398                                // This is one of our own processes; skip it.
2399                                continue;
2400                            }
2401                        }
2402                        nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
2403                    }
2404                    memInfo.readMemInfo();
2405                    synchronized (ActivityManagerService.this) {
2406                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2407                                + (SystemClock.uptimeMillis()-start) + "ms");
2408                        final long cachedKb = memInfo.getCachedSizeKb();
2409                        final long freeKb = memInfo.getFreeSizeKb();
2410                        final long zramKb = memInfo.getZramTotalSizeKb();
2411                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2412                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2413                                kernelKb*1024, nativeTotalPss*1024);
2414                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2415                                nativeTotalPss);
2416                    }
2417                }
2418
2419                int num = 0;
2420                long[] tmp = new long[2];
2421                do {
2422                    ProcessRecord proc;
2423                    int procState;
2424                    int pid;
2425                    long lastPssTime;
2426                    synchronized (ActivityManagerService.this) {
2427                        if (mPendingPssProcesses.size() <= 0) {
2428                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2429                                    "Collected PSS of " + num + " processes in "
2430                                    + (SystemClock.uptimeMillis() - start) + "ms");
2431                            mPendingPssProcesses.clear();
2432                            return;
2433                        }
2434                        proc = mPendingPssProcesses.remove(0);
2435                        procState = proc.pssProcState;
2436                        lastPssTime = proc.lastPssTime;
2437                        if (proc.thread != null && procState == proc.setProcState
2438                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2439                                        < SystemClock.uptimeMillis()) {
2440                            pid = proc.pid;
2441                        } else {
2442                            proc = null;
2443                            pid = 0;
2444                        }
2445                    }
2446                    if (proc != null) {
2447                        long pss = Debug.getPss(pid, tmp, null);
2448                        synchronized (ActivityManagerService.this) {
2449                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2450                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2451                                num++;
2452                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2453                                        SystemClock.uptimeMillis());
2454                            }
2455                        }
2456                    }
2457                } while (true);
2458            }
2459            }
2460        }
2461    };
2462
2463    public void setSystemProcess() {
2464        try {
2465            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2466            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2467            ServiceManager.addService("meminfo", new MemBinder(this));
2468            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2469            ServiceManager.addService("dbinfo", new DbBinder(this));
2470            if (MONITOR_CPU_USAGE) {
2471                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2472            }
2473            ServiceManager.addService("permission", new PermissionController(this));
2474            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2475
2476            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2477                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2478            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2479
2480            synchronized (this) {
2481                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2482                app.persistent = true;
2483                app.pid = MY_PID;
2484                app.maxAdj = ProcessList.SYSTEM_ADJ;
2485                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2486                synchronized (mPidsSelfLocked) {
2487                    mPidsSelfLocked.put(app.pid, app);
2488                }
2489                updateLruProcessLocked(app, false, null);
2490                updateOomAdjLocked();
2491            }
2492        } catch (PackageManager.NameNotFoundException e) {
2493            throw new RuntimeException(
2494                    "Unable to find android system package", e);
2495        }
2496    }
2497
2498    public void setWindowManager(WindowManagerService wm) {
2499        mWindowManager = wm;
2500        mStackSupervisor.setWindowManager(wm);
2501        mActivityStarter.setWindowManager(wm);
2502    }
2503
2504    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2505        mUsageStatsService = usageStatsManager;
2506    }
2507
2508    public void startObservingNativeCrashes() {
2509        final NativeCrashListener ncl = new NativeCrashListener(this);
2510        ncl.start();
2511    }
2512
2513    public IAppOpsService getAppOpsService() {
2514        return mAppOpsService;
2515    }
2516
2517    static class MemBinder extends Binder {
2518        ActivityManagerService mActivityManagerService;
2519        MemBinder(ActivityManagerService activityManagerService) {
2520            mActivityManagerService = activityManagerService;
2521        }
2522
2523        @Override
2524        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2525            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2526                    != PackageManager.PERMISSION_GRANTED) {
2527                pw.println("Permission Denial: can't dump meminfo from from pid="
2528                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2529                        + " without permission " + android.Manifest.permission.DUMP);
2530                return;
2531            }
2532
2533            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2534        }
2535    }
2536
2537    static class GraphicsBinder extends Binder {
2538        ActivityManagerService mActivityManagerService;
2539        GraphicsBinder(ActivityManagerService activityManagerService) {
2540            mActivityManagerService = activityManagerService;
2541        }
2542
2543        @Override
2544        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2545            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2546                    != PackageManager.PERMISSION_GRANTED) {
2547                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2548                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2549                        + " without permission " + android.Manifest.permission.DUMP);
2550                return;
2551            }
2552
2553            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2554        }
2555    }
2556
2557    static class DbBinder extends Binder {
2558        ActivityManagerService mActivityManagerService;
2559        DbBinder(ActivityManagerService activityManagerService) {
2560            mActivityManagerService = activityManagerService;
2561        }
2562
2563        @Override
2564        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2565            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2566                    != PackageManager.PERMISSION_GRANTED) {
2567                pw.println("Permission Denial: can't dump dbinfo from from pid="
2568                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2569                        + " without permission " + android.Manifest.permission.DUMP);
2570                return;
2571            }
2572
2573            mActivityManagerService.dumpDbInfo(fd, pw, args);
2574        }
2575    }
2576
2577    static class CpuBinder extends Binder {
2578        ActivityManagerService mActivityManagerService;
2579        CpuBinder(ActivityManagerService activityManagerService) {
2580            mActivityManagerService = activityManagerService;
2581        }
2582
2583        @Override
2584        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2585            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2586                    != PackageManager.PERMISSION_GRANTED) {
2587                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2588                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2589                        + " without permission " + android.Manifest.permission.DUMP);
2590                return;
2591            }
2592
2593            synchronized (mActivityManagerService.mProcessCpuTracker) {
2594                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2595                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2596                        SystemClock.uptimeMillis()));
2597            }
2598        }
2599    }
2600
2601    public static final class Lifecycle extends SystemService {
2602        private final ActivityManagerService mService;
2603
2604        public Lifecycle(Context context) {
2605            super(context);
2606            mService = new ActivityManagerService(context);
2607        }
2608
2609        @Override
2610        public void onStart() {
2611            mService.start();
2612        }
2613
2614        public ActivityManagerService getService() {
2615            return mService;
2616        }
2617    }
2618
2619    // Note: This method is invoked on the main thread but may need to attach various
2620    // handlers to other threads.  So take care to be explicit about the looper.
2621    public ActivityManagerService(Context systemContext) {
2622        mContext = systemContext;
2623        mFactoryTest = FactoryTest.getMode();
2624        mSystemThread = ActivityThread.currentActivityThread();
2625
2626        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2627
2628        mPermissionReviewRequired = mContext.getResources().getBoolean(
2629                com.android.internal.R.bool.config_permissionReviewRequired);
2630
2631        mHandlerThread = new ServiceThread(TAG,
2632                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2633        mHandlerThread.start();
2634        mHandler = new MainHandler(mHandlerThread.getLooper());
2635        mUiHandler = new UiHandler();
2636
2637        /* static; one-time init here */
2638        if (sKillHandler == null) {
2639            sKillThread = new ServiceThread(TAG + ":kill",
2640                    android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2641            sKillThread.start();
2642            sKillHandler = new KillHandler(sKillThread.getLooper());
2643        }
2644
2645        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2646                "foreground", BROADCAST_FG_TIMEOUT, false);
2647        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2648                "background", BROADCAST_BG_TIMEOUT, true);
2649        mBroadcastQueues[0] = mFgBroadcastQueue;
2650        mBroadcastQueues[1] = mBgBroadcastQueue;
2651
2652        mServices = new ActiveServices(this);
2653        mProviderMap = new ProviderMap(this);
2654        mAppErrors = new AppErrors(mContext, this);
2655
2656        // TODO: Move creation of battery stats service outside of activity manager service.
2657        File dataDir = Environment.getDataDirectory();
2658        File systemDir = new File(dataDir, "system");
2659        systemDir.mkdirs();
2660        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2661        mBatteryStatsService.getActiveStatistics().readLocked();
2662        mBatteryStatsService.scheduleWriteToDisk();
2663        mOnBattery = DEBUG_POWER ? true
2664                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2665        mBatteryStatsService.getActiveStatistics().setCallback(this);
2666
2667        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2668
2669        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2670        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2671                new IAppOpsCallback.Stub() {
2672                    @Override public void opChanged(int op, int uid, String packageName) {
2673                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2674                            if (mAppOpsService.checkOperation(op, uid, packageName)
2675                                    != AppOpsManager.MODE_ALLOWED) {
2676                                runInBackgroundDisabled(uid);
2677                            }
2678                        }
2679                    }
2680                });
2681
2682        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2683
2684        mUserController = new UserController(this);
2685
2686        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2687            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2688
2689        if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
2690            mUseFifoUiScheduling = true;
2691        }
2692
2693        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2694
2695        mConfiguration.setToDefaults();
2696        mConfiguration.setLocales(LocaleList.getDefault());
2697
2698        mConfigurationSeq = mConfiguration.seq = 1;
2699        mProcessCpuTracker.init();
2700
2701        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2702        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2703        mStackSupervisor = new ActivityStackSupervisor(this);
2704        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2705        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2706
2707        mProcessCpuThread = new Thread("CpuTracker") {
2708            @Override
2709            public void run() {
2710                while (true) {
2711                    try {
2712                        try {
2713                            synchronized(this) {
2714                                final long now = SystemClock.uptimeMillis();
2715                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2716                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2717                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2718                                //        + ", write delay=" + nextWriteDelay);
2719                                if (nextWriteDelay < nextCpuDelay) {
2720                                    nextCpuDelay = nextWriteDelay;
2721                                }
2722                                if (nextCpuDelay > 0) {
2723                                    mProcessCpuMutexFree.set(true);
2724                                    this.wait(nextCpuDelay);
2725                                }
2726                            }
2727                        } catch (InterruptedException e) {
2728                        }
2729                        updateCpuStatsNow();
2730                    } catch (Exception e) {
2731                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2732                    }
2733                }
2734            }
2735        };
2736
2737        Watchdog.getInstance().addMonitor(this);
2738        Watchdog.getInstance().addThread(mHandler);
2739    }
2740
2741    public void setSystemServiceManager(SystemServiceManager mgr) {
2742        mSystemServiceManager = mgr;
2743    }
2744
2745    public void setInstaller(Installer installer) {
2746        mInstaller = installer;
2747    }
2748
2749    private void start() {
2750        Process.removeAllProcessGroups();
2751        mProcessCpuThread.start();
2752
2753        mBatteryStatsService.publish(mContext);
2754        mAppOpsService.publish(mContext);
2755        Slog.d("AppOps", "AppOpsService published");
2756        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2757    }
2758
2759    void onUserStoppedLocked(int userId) {
2760        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2761    }
2762
2763    public void initPowerManagement() {
2764        mStackSupervisor.initPowerManagement();
2765        mBatteryStatsService.initPowerManagement();
2766        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2767        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2768        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2769        mVoiceWakeLock.setReferenceCounted(false);
2770    }
2771
2772    @Override
2773    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2774            throws RemoteException {
2775        if (code == SYSPROPS_TRANSACTION) {
2776            // We need to tell all apps about the system property change.
2777            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2778            synchronized(this) {
2779                final int NP = mProcessNames.getMap().size();
2780                for (int ip=0; ip<NP; ip++) {
2781                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2782                    final int NA = apps.size();
2783                    for (int ia=0; ia<NA; ia++) {
2784                        ProcessRecord app = apps.valueAt(ia);
2785                        if (app.thread != null) {
2786                            procs.add(app.thread.asBinder());
2787                        }
2788                    }
2789                }
2790            }
2791
2792            int N = procs.size();
2793            for (int i=0; i<N; i++) {
2794                Parcel data2 = Parcel.obtain();
2795                try {
2796                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2797                } catch (RemoteException e) {
2798                }
2799                data2.recycle();
2800            }
2801        }
2802        try {
2803            return super.onTransact(code, data, reply, flags);
2804        } catch (RuntimeException e) {
2805            // The activity manager only throws security exceptions, so let's
2806            // log all others.
2807            if (!(e instanceof SecurityException)) {
2808                Slog.wtf(TAG, "Activity Manager Crash", e);
2809            }
2810            throw e;
2811        }
2812    }
2813
2814    void updateCpuStats() {
2815        final long now = SystemClock.uptimeMillis();
2816        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2817            return;
2818        }
2819        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2820            synchronized (mProcessCpuThread) {
2821                mProcessCpuThread.notify();
2822            }
2823        }
2824    }
2825
2826    void updateCpuStatsNow() {
2827        synchronized (mProcessCpuTracker) {
2828            mProcessCpuMutexFree.set(false);
2829            final long now = SystemClock.uptimeMillis();
2830            boolean haveNewCpuStats = false;
2831
2832            if (MONITOR_CPU_USAGE &&
2833                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2834                mLastCpuTime.set(now);
2835                mProcessCpuTracker.update();
2836                if (mProcessCpuTracker.hasGoodLastStats()) {
2837                    haveNewCpuStats = true;
2838                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2839                    //Slog.i(TAG, "Total CPU usage: "
2840                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2841
2842                    // Slog the cpu usage if the property is set.
2843                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2844                        int user = mProcessCpuTracker.getLastUserTime();
2845                        int system = mProcessCpuTracker.getLastSystemTime();
2846                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2847                        int irq = mProcessCpuTracker.getLastIrqTime();
2848                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2849                        int idle = mProcessCpuTracker.getLastIdleTime();
2850
2851                        int total = user + system + iowait + irq + softIrq + idle;
2852                        if (total == 0) total = 1;
2853
2854                        EventLog.writeEvent(EventLogTags.CPU,
2855                                ((user+system+iowait+irq+softIrq) * 100) / total,
2856                                (user * 100) / total,
2857                                (system * 100) / total,
2858                                (iowait * 100) / total,
2859                                (irq * 100) / total,
2860                                (softIrq * 100) / total);
2861                    }
2862                }
2863            }
2864
2865            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2866            synchronized(bstats) {
2867                synchronized(mPidsSelfLocked) {
2868                    if (haveNewCpuStats) {
2869                        if (bstats.startAddingCpuLocked()) {
2870                            int totalUTime = 0;
2871                            int totalSTime = 0;
2872                            final int N = mProcessCpuTracker.countStats();
2873                            for (int i=0; i<N; i++) {
2874                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2875                                if (!st.working) {
2876                                    continue;
2877                                }
2878                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2879                                totalUTime += st.rel_utime;
2880                                totalSTime += st.rel_stime;
2881                                if (pr != null) {
2882                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2883                                    if (ps == null || !ps.isActive()) {
2884                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2885                                                pr.info.uid, pr.processName);
2886                                    }
2887                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2888                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2889                                } else {
2890                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2891                                    if (ps == null || !ps.isActive()) {
2892                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2893                                                bstats.mapUid(st.uid), st.name);
2894                                    }
2895                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2896                                }
2897                            }
2898                            final int userTime = mProcessCpuTracker.getLastUserTime();
2899                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2900                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2901                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2902                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2903                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2904                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2905                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2906                        }
2907                    }
2908                }
2909
2910                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2911                    mLastWriteTime = now;
2912                    mBatteryStatsService.scheduleWriteToDisk();
2913                }
2914            }
2915        }
2916    }
2917
2918    @Override
2919    public void batteryNeedsCpuUpdate() {
2920        updateCpuStatsNow();
2921    }
2922
2923    @Override
2924    public void batteryPowerChanged(boolean onBattery) {
2925        // When plugging in, update the CPU stats first before changing
2926        // the plug state.
2927        updateCpuStatsNow();
2928        synchronized (this) {
2929            synchronized(mPidsSelfLocked) {
2930                mOnBattery = DEBUG_POWER ? true : onBattery;
2931            }
2932        }
2933    }
2934
2935    @Override
2936    public void batterySendBroadcast(Intent intent) {
2937        synchronized (this) {
2938            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2939                    AppOpsManager.OP_NONE, null, false, false,
2940                    -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2941        }
2942    }
2943
2944    /**
2945     * Initialize the application bind args. These are passed to each
2946     * process when the bindApplication() IPC is sent to the process. They're
2947     * lazily setup to make sure the services are running when they're asked for.
2948     */
2949    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2950        // Isolated processes won't get this optimization, so that we don't
2951        // violate the rules about which services they have access to.
2952        if (isolated) {
2953            if (mIsolatedAppBindArgs == null) {
2954                mIsolatedAppBindArgs = new HashMap<>();
2955                mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
2956            }
2957            return mIsolatedAppBindArgs;
2958        }
2959
2960        if (mAppBindArgs == null) {
2961            mAppBindArgs = new HashMap<>();
2962
2963            // Setup the application init args
2964            mAppBindArgs.put("package", ServiceManager.getService("package"));
2965            mAppBindArgs.put("window", ServiceManager.getService("window"));
2966            mAppBindArgs.put(Context.ALARM_SERVICE,
2967                    ServiceManager.getService(Context.ALARM_SERVICE));
2968        }
2969        return mAppBindArgs;
2970    }
2971
2972    boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2973        if (r == null || mFocusedActivity == r) {
2974            return false;
2975        }
2976
2977        if (!r.isFocusable()) {
2978            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2979            return false;
2980        }
2981
2982        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2983
2984        final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2985        if (wasDoingSetFocusedActivity) Slog.w(TAG,
2986                "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2987        mDoingSetFocusedActivity = true;
2988
2989        final ActivityRecord last = mFocusedActivity;
2990        mFocusedActivity = r;
2991        if (r.task.isApplicationTask()) {
2992            if (mCurAppTimeTracker != r.appTimeTracker) {
2993                // We are switching app tracking.  Complete the current one.
2994                if (mCurAppTimeTracker != null) {
2995                    mCurAppTimeTracker.stop();
2996                    mHandler.obtainMessage(
2997                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2998                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2999                    mCurAppTimeTracker = null;
3000                }
3001                if (r.appTimeTracker != null) {
3002                    mCurAppTimeTracker = r.appTimeTracker;
3003                    startTimeTrackingFocusedActivityLocked();
3004                }
3005            } else {
3006                startTimeTrackingFocusedActivityLocked();
3007            }
3008        } else {
3009            r.appTimeTracker = null;
3010        }
3011        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
3012        // TODO: Probably not, because we don't want to resume voice on switching
3013        // back to this activity
3014        if (r.task.voiceInteractor != null) {
3015            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
3016        } else {
3017            finishRunningVoiceLocked();
3018            IVoiceInteractionSession session;
3019            if (last != null && ((session = last.task.voiceSession) != null
3020                    || (session = last.voiceSession) != null)) {
3021                // We had been in a voice interaction session, but now focused has
3022                // move to something different.  Just finish the session, we can't
3023                // return to it and retain the proper state and synchronization with
3024                // the voice interaction service.
3025                finishVoiceTask(session);
3026            }
3027        }
3028        if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
3029            mWindowManager.setFocusedApp(r.appToken, true);
3030        }
3031        applyUpdateLockStateLocked(r);
3032        applyUpdateVrModeLocked(r);
3033        if (mFocusedActivity.userId != mLastFocusedUserId) {
3034            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3035            mHandler.obtainMessage(
3036                    FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
3037            mLastFocusedUserId = mFocusedActivity.userId;
3038        }
3039
3040        // Log a warning if the focused app is changed during the process. This could
3041        // indicate a problem of the focus setting logic!
3042        if (mFocusedActivity != r) Slog.w(TAG,
3043                "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
3044        mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
3045
3046        EventLogTags.writeAmFocusedActivity(
3047                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
3048                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
3049                reason);
3050        return true;
3051    }
3052
3053    final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
3054        if (mFocusedActivity != goingAway) {
3055            return;
3056        }
3057
3058        final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
3059        if (focusedStack != null) {
3060            final ActivityRecord top = focusedStack.topActivity();
3061            if (top != null && top.userId != mLastFocusedUserId) {
3062                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3063                mHandler.sendMessage(
3064                        mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
3065                mLastFocusedUserId = top.userId;
3066            }
3067        }
3068
3069        // Try to move focus to another activity if possible.
3070        if (setFocusedActivityLocked(
3071                focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
3072            return;
3073        }
3074
3075        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
3076                + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
3077        mFocusedActivity = null;
3078        EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
3079    }
3080
3081    @Override
3082    public void setFocusedStack(int stackId) {
3083        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3084        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3085        final long callingId = Binder.clearCallingIdentity();
3086        try {
3087            synchronized (this) {
3088                final ActivityStack stack = mStackSupervisor.getStack(stackId);
3089                if (stack == null) {
3090                    return;
3091                }
3092                final ActivityRecord r = stack.topRunningActivityLocked();
3093                if (setFocusedActivityLocked(r, "setFocusedStack")) {
3094                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3095                }
3096            }
3097        } finally {
3098            Binder.restoreCallingIdentity(callingId);
3099        }
3100    }
3101
3102    @Override
3103    public void setFocusedTask(int taskId) {
3104        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3105        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3106        final long callingId = Binder.clearCallingIdentity();
3107        try {
3108            synchronized (this) {
3109                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3110                if (task == null) {
3111                    return;
3112                }
3113                if (mUserController.shouldConfirmCredentials(task.userId)) {
3114                    mActivityStarter.showConfirmDeviceCredential(task.userId);
3115                    if (task.stack != null && task.stack.mStackId == FREEFORM_WORKSPACE_STACK_ID) {
3116                        mStackSupervisor.moveTaskToStackLocked(task.taskId,
3117                                FULLSCREEN_WORKSPACE_STACK_ID, !ON_TOP, !FORCE_FOCUS,
3118                                "setFocusedTask", ANIMATE);
3119                    }
3120                    return;
3121                }
3122                final ActivityRecord r = task.topRunningActivityLocked();
3123                if (setFocusedActivityLocked(r, "setFocusedTask")) {
3124                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3125                }
3126            }
3127        } finally {
3128            Binder.restoreCallingIdentity(callingId);
3129        }
3130    }
3131
3132    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3133    @Override
3134    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3135        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3136        synchronized (this) {
3137            if (listener != null) {
3138                mTaskStackListeners.register(listener);
3139            }
3140        }
3141    }
3142
3143    @Override
3144    public void notifyActivityDrawn(IBinder token) {
3145        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3146        synchronized (this) {
3147            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3148            if (r != null) {
3149                r.task.stack.notifyActivityDrawnLocked(r);
3150            }
3151        }
3152    }
3153
3154    final void applyUpdateLockStateLocked(ActivityRecord r) {
3155        // Modifications to the UpdateLock state are done on our handler, outside
3156        // the activity manager's locks.  The new state is determined based on the
3157        // state *now* of the relevant activity record.  The object is passed to
3158        // the handler solely for logging detail, not to be consulted/modified.
3159        final boolean nextState = r != null && r.immersive;
3160        mHandler.sendMessage(
3161                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3162    }
3163
3164    final void applyUpdateVrModeLocked(ActivityRecord r) {
3165        mHandler.sendMessage(
3166                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3167    }
3168
3169    private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
3170        mHandler.sendMessage(
3171                mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
3172    }
3173
3174    private void applyVrMode(boolean enabled, ComponentName packageName, int userId,
3175            ComponentName callingPackage, boolean immediate) {
3176        VrManagerInternal vrService =
3177                LocalServices.getService(VrManagerInternal.class);
3178        if (immediate) {
3179            vrService.setVrModeImmediate(enabled, packageName, userId, callingPackage);
3180        } else {
3181            vrService.setVrMode(enabled, packageName, userId, callingPackage);
3182        }
3183    }
3184
3185    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3186        Message msg = Message.obtain();
3187        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3188        msg.obj = r.task.askedCompatMode ? null : r;
3189        mUiHandler.sendMessage(msg);
3190    }
3191
3192    final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3193        if (mConfiguration.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3194                && r.appInfo.requiresSmallestWidthDp > mConfiguration.smallestScreenWidthDp) {
3195            final Message msg = Message.obtain();
3196            msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3197            msg.obj = r;
3198            mUiHandler.sendMessage(msg);
3199        }
3200    }
3201
3202    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3203            String what, Object obj, ProcessRecord srcApp) {
3204        app.lastActivityTime = now;
3205
3206        if (app.activities.size() > 0) {
3207            // Don't want to touch dependent processes that are hosting activities.
3208            return index;
3209        }
3210
3211        int lrui = mLruProcesses.lastIndexOf(app);
3212        if (lrui < 0) {
3213            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3214                    + what + " " + obj + " from " + srcApp);
3215            return index;
3216        }
3217
3218        if (lrui >= index) {
3219            // Don't want to cause this to move dependent processes *back* in the
3220            // list as if they were less frequently used.
3221            return index;
3222        }
3223
3224        if (lrui >= mLruProcessActivityStart) {
3225            // Don't want to touch dependent processes that are hosting activities.
3226            return index;
3227        }
3228
3229        mLruProcesses.remove(lrui);
3230        if (index > 0) {
3231            index--;
3232        }
3233        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3234                + " in LRU list: " + app);
3235        mLruProcesses.add(index, app);
3236        return index;
3237    }
3238
3239    static void killProcessGroup(int uid, int pid) {
3240        if (sKillHandler != null) {
3241            sKillHandler.sendMessage(
3242                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3243        } else {
3244            Slog.w(TAG, "Asked to kill process group before system bringup!");
3245            Process.killProcessGroup(uid, pid);
3246        }
3247    }
3248
3249    final void removeLruProcessLocked(ProcessRecord app) {
3250        int lrui = mLruProcesses.lastIndexOf(app);
3251        if (lrui >= 0) {
3252            if (!app.killed) {
3253                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3254                Process.killProcessQuiet(app.pid);
3255                killProcessGroup(app.uid, app.pid);
3256            }
3257            if (lrui <= mLruProcessActivityStart) {
3258                mLruProcessActivityStart--;
3259            }
3260            if (lrui <= mLruProcessServiceStart) {
3261                mLruProcessServiceStart--;
3262            }
3263            mLruProcesses.remove(lrui);
3264        }
3265    }
3266
3267    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3268            ProcessRecord client) {
3269        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3270                || app.treatLikeActivity;
3271        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3272        if (!activityChange && hasActivity) {
3273            // The process has activities, so we are only allowing activity-based adjustments
3274            // to move it.  It should be kept in the front of the list with other
3275            // processes that have activities, and we don't want those to change their
3276            // order except due to activity operations.
3277            return;
3278        }
3279
3280        mLruSeq++;
3281        final long now = SystemClock.uptimeMillis();
3282        app.lastActivityTime = now;
3283
3284        // First a quick reject: if the app is already at the position we will
3285        // put it, then there is nothing to do.
3286        if (hasActivity) {
3287            final int N = mLruProcesses.size();
3288            if (N > 0 && mLruProcesses.get(N-1) == app) {
3289                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3290                return;
3291            }
3292        } else {
3293            if (mLruProcessServiceStart > 0
3294                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3295                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3296                return;
3297            }
3298        }
3299
3300        int lrui = mLruProcesses.lastIndexOf(app);
3301
3302        if (app.persistent && lrui >= 0) {
3303            // We don't care about the position of persistent processes, as long as
3304            // they are in the list.
3305            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3306            return;
3307        }
3308
3309        /* In progress: compute new position first, so we can avoid doing work
3310           if the process is not actually going to move.  Not yet working.
3311        int addIndex;
3312        int nextIndex;
3313        boolean inActivity = false, inService = false;
3314        if (hasActivity) {
3315            // Process has activities, put it at the very tipsy-top.
3316            addIndex = mLruProcesses.size();
3317            nextIndex = mLruProcessServiceStart;
3318            inActivity = true;
3319        } else if (hasService) {
3320            // Process has services, put it at the top of the service list.
3321            addIndex = mLruProcessActivityStart;
3322            nextIndex = mLruProcessServiceStart;
3323            inActivity = true;
3324            inService = true;
3325        } else  {
3326            // Process not otherwise of interest, it goes to the top of the non-service area.
3327            addIndex = mLruProcessServiceStart;
3328            if (client != null) {
3329                int clientIndex = mLruProcesses.lastIndexOf(client);
3330                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3331                        + app);
3332                if (clientIndex >= 0 && addIndex > clientIndex) {
3333                    addIndex = clientIndex;
3334                }
3335            }
3336            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3337        }
3338
3339        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3340                + mLruProcessActivityStart + "): " + app);
3341        */
3342
3343        if (lrui >= 0) {
3344            if (lrui < mLruProcessActivityStart) {
3345                mLruProcessActivityStart--;
3346            }
3347            if (lrui < mLruProcessServiceStart) {
3348                mLruProcessServiceStart--;
3349            }
3350            /*
3351            if (addIndex > lrui) {
3352                addIndex--;
3353            }
3354            if (nextIndex > lrui) {
3355                nextIndex--;
3356            }
3357            */
3358            mLruProcesses.remove(lrui);
3359        }
3360
3361        /*
3362        mLruProcesses.add(addIndex, app);
3363        if (inActivity) {
3364            mLruProcessActivityStart++;
3365        }
3366        if (inService) {
3367            mLruProcessActivityStart++;
3368        }
3369        */
3370
3371        int nextIndex;
3372        if (hasActivity) {
3373            final int N = mLruProcesses.size();
3374            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3375                // Process doesn't have activities, but has clients with
3376                // activities...  move it up, but one below the top (the top
3377                // should always have a real activity).
3378                if (DEBUG_LRU) Slog.d(TAG_LRU,
3379                        "Adding to second-top of LRU activity list: " + app);
3380                mLruProcesses.add(N - 1, app);
3381                // To keep it from spamming the LRU list (by making a bunch of clients),
3382                // we will push down any other entries owned by the app.
3383                final int uid = app.info.uid;
3384                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3385                    ProcessRecord subProc = mLruProcesses.get(i);
3386                    if (subProc.info.uid == uid) {
3387                        // We want to push this one down the list.  If the process after
3388                        // it is for the same uid, however, don't do so, because we don't
3389                        // want them internally to be re-ordered.
3390                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3391                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3392                                    "Pushing uid " + uid + " swapping at " + i + ": "
3393                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3394                            ProcessRecord tmp = mLruProcesses.get(i);
3395                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3396                            mLruProcesses.set(i - 1, tmp);
3397                            i--;
3398                        }
3399                    } else {
3400                        // A gap, we can stop here.
3401                        break;
3402                    }
3403                }
3404            } else {
3405                // Process has activities, put it at the very tipsy-top.
3406                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3407                mLruProcesses.add(app);
3408            }
3409            nextIndex = mLruProcessServiceStart;
3410        } else if (hasService) {
3411            // Process has services, put it at the top of the service list.
3412            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3413            mLruProcesses.add(mLruProcessActivityStart, app);
3414            nextIndex = mLruProcessServiceStart;
3415            mLruProcessActivityStart++;
3416        } else  {
3417            // Process not otherwise of interest, it goes to the top of the non-service area.
3418            int index = mLruProcessServiceStart;
3419            if (client != null) {
3420                // If there is a client, don't allow the process to be moved up higher
3421                // in the list than that client.
3422                int clientIndex = mLruProcesses.lastIndexOf(client);
3423                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3424                        + " when updating " + app);
3425                if (clientIndex <= lrui) {
3426                    // Don't allow the client index restriction to push it down farther in the
3427                    // list than it already is.
3428                    clientIndex = lrui;
3429                }
3430                if (clientIndex >= 0 && index > clientIndex) {
3431                    index = clientIndex;
3432                }
3433            }
3434            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3435            mLruProcesses.add(index, app);
3436            nextIndex = index-1;
3437            mLruProcessActivityStart++;
3438            mLruProcessServiceStart++;
3439        }
3440
3441        // If the app is currently using a content provider or service,
3442        // bump those processes as well.
3443        for (int j=app.connections.size()-1; j>=0; j--) {
3444            ConnectionRecord cr = app.connections.valueAt(j);
3445            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3446                    && cr.binding.service.app != null
3447                    && cr.binding.service.app.lruSeq != mLruSeq
3448                    && !cr.binding.service.app.persistent) {
3449                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3450                        "service connection", cr, app);
3451            }
3452        }
3453        for (int j=app.conProviders.size()-1; j>=0; j--) {
3454            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3455            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3456                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3457                        "provider reference", cpr, app);
3458            }
3459        }
3460    }
3461
3462    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3463        if (uid == Process.SYSTEM_UID) {
3464            // The system gets to run in any process.  If there are multiple
3465            // processes with the same uid, just pick the first (this
3466            // should never happen).
3467            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3468            if (procs == null) return null;
3469            final int procCount = procs.size();
3470            for (int i = 0; i < procCount; i++) {
3471                final int procUid = procs.keyAt(i);
3472                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3473                    // Don't use an app process or different user process for system component.
3474                    continue;
3475                }
3476                return procs.valueAt(i);
3477            }
3478        }
3479        ProcessRecord proc = mProcessNames.get(processName, uid);
3480        if (false && proc != null && !keepIfLarge
3481                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3482                && proc.lastCachedPss >= 4000) {
3483            // Turn this condition on to cause killing to happen regularly, for testing.
3484            if (proc.baseProcessTracker != null) {
3485                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3486            }
3487            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3488        } else if (proc != null && !keepIfLarge
3489                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3490                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3491            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3492            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3493                if (proc.baseProcessTracker != null) {
3494                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3495                }
3496                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3497            }
3498        }
3499        return proc;
3500    }
3501
3502    void notifyPackageUse(String packageName, int reason) {
3503        IPackageManager pm = AppGlobals.getPackageManager();
3504        try {
3505            pm.notifyPackageUse(packageName, reason);
3506        } catch (RemoteException e) {
3507        }
3508    }
3509
3510    boolean isNextTransitionForward() {
3511        int transit = mWindowManager.getPendingAppTransition();
3512        return transit == TRANSIT_ACTIVITY_OPEN
3513                || transit == TRANSIT_TASK_OPEN
3514                || transit == TRANSIT_TASK_TO_FRONT;
3515    }
3516
3517    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3518            String processName, String abiOverride, int uid, Runnable crashHandler) {
3519        synchronized(this) {
3520            ApplicationInfo info = new ApplicationInfo();
3521            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3522            // For isolated processes, the former contains the parent's uid and the latter the
3523            // actual uid of the isolated process.
3524            // In the special case introduced by this method (which is, starting an isolated
3525            // process directly from the SystemServer without an actual parent app process) the
3526            // closest thing to a parent's uid is SYSTEM_UID.
3527            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3528            // the |isolated| logic in the ProcessRecord constructor.
3529            info.uid = Process.SYSTEM_UID;
3530            info.processName = processName;
3531            info.className = entryPoint;
3532            info.packageName = "android";
3533            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3534                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3535                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3536                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3537                    crashHandler);
3538            return proc != null ? proc.pid : 0;
3539        }
3540    }
3541
3542    final ProcessRecord startProcessLocked(String processName,
3543            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3544            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3545            boolean isolated, boolean keepIfLarge) {
3546        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3547                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3548                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3549                null /* crashHandler */);
3550    }
3551
3552    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3553            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3554            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3555            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3556        long startTime = SystemClock.elapsedRealtime();
3557        ProcessRecord app;
3558        if (!isolated) {
3559            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3560            checkTime(startTime, "startProcess: after getProcessRecord");
3561
3562            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3563                // If we are in the background, then check to see if this process
3564                // is bad.  If so, we will just silently fail.
3565                if (mAppErrors.isBadProcessLocked(info)) {
3566                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3567                            + "/" + info.processName);
3568                    return null;
3569                }
3570            } else {
3571                // When the user is explicitly starting a process, then clear its
3572                // crash count so that we won't make it bad until they see at
3573                // least one crash dialog again, and make the process good again
3574                // if it had been bad.
3575                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3576                        + "/" + info.processName);
3577                mAppErrors.resetProcessCrashTimeLocked(info);
3578                if (mAppErrors.isBadProcessLocked(info)) {
3579                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3580                            UserHandle.getUserId(info.uid), info.uid,
3581                            info.processName);
3582                    mAppErrors.clearBadProcessLocked(info);
3583                    if (app != null) {
3584                        app.bad = false;
3585                    }
3586                }
3587            }
3588        } else {
3589            // If this is an isolated process, it can't re-use an existing process.
3590            app = null;
3591        }
3592
3593        // app launch boost for big.little configurations
3594        // use cpusets to migrate freshly launched tasks to big cores
3595        nativeMigrateToBoost();
3596        mIsBoosted = true;
3597        mBoostStartTime = SystemClock.uptimeMillis();
3598        Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3599        mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3600
3601        // We don't have to do anything more if:
3602        // (1) There is an existing application record; and
3603        // (2) The caller doesn't think it is dead, OR there is no thread
3604        //     object attached to it so we know it couldn't have crashed; and
3605        // (3) There is a pid assigned to it, so it is either starting or
3606        //     already running.
3607        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3608                + " app=" + app + " knownToBeDead=" + knownToBeDead
3609                + " thread=" + (app != null ? app.thread : null)
3610                + " pid=" + (app != null ? app.pid : -1));
3611        if (app != null && app.pid > 0) {
3612            if ((!knownToBeDead && !app.killed) || app.thread == null) {
3613                // We already have the app running, or are waiting for it to
3614                // come up (we have a pid but not yet its thread), so keep it.
3615                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3616                // If this is a new package in the process, add the package to the list
3617                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3618                checkTime(startTime, "startProcess: done, added package to proc");
3619                return app;
3620            }
3621
3622            // An application record is attached to a previous process,
3623            // clean it up now.
3624            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3625            checkTime(startTime, "startProcess: bad proc running, killing");
3626            killProcessGroup(app.uid, app.pid);
3627            handleAppDiedLocked(app, true, true);
3628            checkTime(startTime, "startProcess: done killing old proc");
3629        }
3630
3631        String hostingNameStr = hostingName != null
3632                ? hostingName.flattenToShortString() : null;
3633
3634        if (app == null) {
3635            checkTime(startTime, "startProcess: creating new process record");
3636            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3637            if (app == null) {
3638                Slog.w(TAG, "Failed making new process record for "
3639                        + processName + "/" + info.uid + " isolated=" + isolated);
3640                return null;
3641            }
3642            app.crashHandler = crashHandler;
3643            checkTime(startTime, "startProcess: done creating new process record");
3644        } else {
3645            // If this is a new package in the process, add the package to the list
3646            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3647            checkTime(startTime, "startProcess: added package to existing proc");
3648        }
3649
3650        // If the system is not ready yet, then hold off on starting this
3651        // process until it is.
3652        if (!mProcessesReady
3653                && !isAllowedWhileBooting(info)
3654                && !allowWhileBooting) {
3655            if (!mProcessesOnHold.contains(app)) {
3656                mProcessesOnHold.add(app);
3657            }
3658            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3659                    "System not ready, putting on hold: " + app);
3660            checkTime(startTime, "startProcess: returning with proc on hold");
3661            return app;
3662        }
3663
3664        checkTime(startTime, "startProcess: stepping in to startProcess");
3665        startProcessLocked(
3666                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3667        checkTime(startTime, "startProcess: done starting proc!");
3668        return (app.pid != 0) ? app : null;
3669    }
3670
3671    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3672        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3673    }
3674
3675    private final void startProcessLocked(ProcessRecord app,
3676            String hostingType, String hostingNameStr) {
3677        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3678                null /* entryPoint */, null /* entryPointArgs */);
3679    }
3680
3681    private final void startProcessLocked(ProcessRecord app, String hostingType,
3682            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3683        long startTime = SystemClock.elapsedRealtime();
3684        if (app.pid > 0 && app.pid != MY_PID) {
3685            checkTime(startTime, "startProcess: removing from pids map");
3686            synchronized (mPidsSelfLocked) {
3687                mPidsSelfLocked.remove(app.pid);
3688                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3689            }
3690            checkTime(startTime, "startProcess: done removing from pids map");
3691            app.setPid(0);
3692        }
3693
3694        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3695                "startProcessLocked removing on hold: " + app);
3696        mProcessesOnHold.remove(app);
3697
3698        checkTime(startTime, "startProcess: starting to update cpu stats");
3699        updateCpuStats();
3700        checkTime(startTime, "startProcess: done updating cpu stats");
3701
3702        try {
3703            try {
3704                final int userId = UserHandle.getUserId(app.uid);
3705                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3706            } catch (RemoteException e) {
3707                throw e.rethrowAsRuntimeException();
3708            }
3709
3710            int uid = app.uid;
3711            int[] gids = null;
3712            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3713            if (!app.isolated) {
3714                int[] permGids = null;
3715                try {
3716                    checkTime(startTime, "startProcess: getting gids from package manager");
3717                    final IPackageManager pm = AppGlobals.getPackageManager();
3718                    permGids = pm.getPackageGids(app.info.packageName,
3719                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3720                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3721                            MountServiceInternal.class);
3722                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3723                            app.info.packageName);
3724                } catch (RemoteException e) {
3725                    throw e.rethrowAsRuntimeException();
3726                }
3727
3728                /*
3729                 * Add shared application and profile GIDs so applications can share some
3730                 * resources like shared libraries and access user-wide resources
3731                 */
3732                if (ArrayUtils.isEmpty(permGids)) {
3733                    gids = new int[3];
3734                } else {
3735                    gids = new int[permGids.length + 3];
3736                    System.arraycopy(permGids, 0, gids, 3, permGids.length);
3737                }
3738                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3739                gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
3740                gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3741            }
3742            checkTime(startTime, "startProcess: building args");
3743            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3744                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3745                        && mTopComponent != null
3746                        && app.processName.equals(mTopComponent.getPackageName())) {
3747                    uid = 0;
3748                }
3749                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3750                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3751                    uid = 0;
3752                }
3753            }
3754            int debugFlags = 0;
3755            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3756                debugFlags |= Zygote.DEBUG_ENABLE_JDWP;
3757                debugFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE;
3758                // Also turn on CheckJNI for debuggable apps. It's quite
3759                // awkward to turn on otherwise.
3760                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3761            }
3762            // Run the app in safe mode if its manifest requests so or the
3763            // system is booted in safe mode.
3764            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3765                mSafeMode == true) {
3766                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3767            }
3768            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3769                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3770            }
3771            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3772            if ("true".equals(genDebugInfoProperty)) {
3773                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3774            }
3775            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3776                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3777            }
3778            if ("1".equals(SystemProperties.get("debug.assert"))) {
3779                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3780            }
3781            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3782                // Enable all debug flags required by the native debugger.
3783                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3784                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3785                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3786                mNativeDebuggingApp = null;
3787            }
3788
3789            String invokeWith = null;
3790            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3791                // Debuggable apps may include a wrapper script with their library directory.
3792                String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
3793                if (new File(wrapperFileName).exists()) {
3794                    invokeWith = "/system/bin/logwrapper " + wrapperFileName;
3795                }
3796            }
3797
3798            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3799            if (requiredAbi == null) {
3800                requiredAbi = Build.SUPPORTED_ABIS[0];
3801            }
3802
3803            String instructionSet = null;
3804            if (app.info.primaryCpuAbi != null) {
3805                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3806            }
3807
3808            app.gids = gids;
3809            app.requiredAbi = requiredAbi;
3810            app.instructionSet = instructionSet;
3811
3812            // Start the process.  It will either succeed and return a result containing
3813            // the PID of the new process, or else throw a RuntimeException.
3814            boolean isActivityProcess = (entryPoint == null);
3815            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3816            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3817                    app.processName);
3818            checkTime(startTime, "startProcess: asking zygote to start proc");
3819            Process.ProcessStartResult startResult;
3820            if (hostingType.equals("webview_service")) {
3821                startResult = Process.startWebView(entryPoint,
3822                        app.processName, uid, uid, gids, debugFlags, mountExternal,
3823                        app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3824                        app.info.dataDir, null, entryPointArgs);
3825            } else {
3826                startResult = Process.start(entryPoint,
3827                        app.processName, uid, uid, gids, debugFlags, mountExternal,
3828                        app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3829                        app.info.dataDir, invokeWith, entryPointArgs);
3830            }
3831            checkTime(startTime, "startProcess: returned from zygote!");
3832            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3833
3834            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3835            checkTime(startTime, "startProcess: done updating battery stats");
3836
3837            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3838                    UserHandle.getUserId(uid), startResult.pid, uid,
3839                    app.processName, hostingType,
3840                    hostingNameStr != null ? hostingNameStr : "");
3841
3842            try {
3843                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3844                        app.info.seinfo, app.info.sourceDir, startResult.pid);
3845            } catch (RemoteException ex) {
3846                // Ignore
3847            }
3848
3849            if (app.persistent) {
3850                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3851            }
3852
3853            checkTime(startTime, "startProcess: building log message");
3854            StringBuilder buf = mStringBuilder;
3855            buf.setLength(0);
3856            buf.append("Start proc ");
3857            buf.append(startResult.pid);
3858            buf.append(':');
3859            buf.append(app.processName);
3860            buf.append('/');
3861            UserHandle.formatUid(buf, uid);
3862            if (!isActivityProcess) {
3863                buf.append(" [");
3864                buf.append(entryPoint);
3865                buf.append("]");
3866            }
3867            buf.append(" for ");
3868            buf.append(hostingType);
3869            if (hostingNameStr != null) {
3870                buf.append(" ");
3871                buf.append(hostingNameStr);
3872            }
3873            Slog.i(TAG, buf.toString());
3874            app.setPid(startResult.pid);
3875            app.usingWrapper = startResult.usingWrapper;
3876            app.removed = false;
3877            app.killed = false;
3878            app.killedByAm = false;
3879            checkTime(startTime, "startProcess: starting to update pids map");
3880            ProcessRecord oldApp;
3881            synchronized (mPidsSelfLocked) {
3882                oldApp = mPidsSelfLocked.get(startResult.pid);
3883            }
3884            // If there is already an app occupying that pid that hasn't been cleaned up
3885            if (oldApp != null && !app.isolated) {
3886                // Clean up anything relating to this pid first
3887                Slog.w(TAG, "Reusing pid " + startResult.pid
3888                        + " while app is still mapped to it");
3889                cleanUpApplicationRecordLocked(oldApp, false, false, -1,
3890                        true /*replacingPid*/);
3891            }
3892            synchronized (mPidsSelfLocked) {
3893                this.mPidsSelfLocked.put(startResult.pid, app);
3894                if (isActivityProcess) {
3895                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3896                    msg.obj = app;
3897                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3898                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3899                }
3900            }
3901            checkTime(startTime, "startProcess: done updating pids map");
3902        } catch (RuntimeException e) {
3903            Slog.e(TAG, "Failure starting process " + app.processName, e);
3904
3905            // Something went very wrong while trying to start this process; one
3906            // common case is when the package is frozen due to an active
3907            // upgrade. To recover, clean up any active bookkeeping related to
3908            // starting this process. (We already invoked this method once when
3909            // the package was initially frozen through KILL_APPLICATION_MSG, so
3910            // it doesn't hurt to use it again.)
3911            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3912                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3913        }
3914    }
3915
3916    void updateUsageStats(ActivityRecord component, boolean resumed) {
3917        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3918                "updateUsageStats: comp=" + component + "res=" + resumed);
3919        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3920        if (resumed) {
3921            if (mUsageStatsService != null) {
3922                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3923                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3924            }
3925            synchronized (stats) {
3926                stats.noteActivityResumedLocked(component.app.uid);
3927            }
3928        } else {
3929            if (mUsageStatsService != null) {
3930                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3931                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3932            }
3933            synchronized (stats) {
3934                stats.noteActivityPausedLocked(component.app.uid);
3935            }
3936        }
3937    }
3938
3939    Intent getHomeIntent() {
3940        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3941        intent.setComponent(mTopComponent);
3942        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3943        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3944            intent.addCategory(Intent.CATEGORY_HOME);
3945        }
3946        return intent;
3947    }
3948
3949    boolean startHomeActivityLocked(int userId, String reason) {
3950        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3951                && mTopAction == null) {
3952            // We are running in factory test mode, but unable to find
3953            // the factory test app, so just sit around displaying the
3954            // error message and don't try to start anything.
3955            return false;
3956        }
3957        Intent intent = getHomeIntent();
3958        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3959        if (aInfo != null) {
3960            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3961            // Don't do this if the home app is currently being
3962            // instrumented.
3963            aInfo = new ActivityInfo(aInfo);
3964            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3965            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3966                    aInfo.applicationInfo.uid, true);
3967            if (app == null || app.instrumentationClass == null) {
3968                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3969                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3970            }
3971        } else {
3972            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3973        }
3974
3975        return true;
3976    }
3977
3978    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3979        ActivityInfo ai = null;
3980        ComponentName comp = intent.getComponent();
3981        try {
3982            if (comp != null) {
3983                // Factory test.
3984                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3985            } else {
3986                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3987                        intent,
3988                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3989                        flags, userId);
3990
3991                if (info != null) {
3992                    ai = info.activityInfo;
3993                }
3994            }
3995        } catch (RemoteException e) {
3996            // ignore
3997        }
3998
3999        return ai;
4000    }
4001
4002    /**
4003     * Starts the "new version setup screen" if appropriate.
4004     */
4005    void startSetupActivityLocked() {
4006        // Only do this once per boot.
4007        if (mCheckedForSetup) {
4008            return;
4009        }
4010
4011        // We will show this screen if the current one is a different
4012        // version than the last one shown, and we are not running in
4013        // low-level factory test mode.
4014        final ContentResolver resolver = mContext.getContentResolver();
4015        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
4016                Settings.Global.getInt(resolver,
4017                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
4018            mCheckedForSetup = true;
4019
4020            // See if we should be showing the platform update setup UI.
4021            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
4022            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
4023                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
4024            if (!ris.isEmpty()) {
4025                final ResolveInfo ri = ris.get(0);
4026                String vers = ri.activityInfo.metaData != null
4027                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
4028                        : null;
4029                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
4030                    vers = ri.activityInfo.applicationInfo.metaData.getString(
4031                            Intent.METADATA_SETUP_VERSION);
4032                }
4033                String lastVers = Settings.Secure.getString(
4034                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
4035                if (vers != null && !vers.equals(lastVers)) {
4036                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
4037                    intent.setComponent(new ComponentName(
4038                            ri.activityInfo.packageName, ri.activityInfo.name));
4039                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
4040                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
4041                            null, 0, 0, 0, null, false, false, null, null, null);
4042                }
4043            }
4044        }
4045    }
4046
4047    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
4048        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
4049    }
4050
4051    void enforceNotIsolatedCaller(String caller) {
4052        if (UserHandle.isIsolated(Binder.getCallingUid())) {
4053            throw new SecurityException("Isolated process not allowed to call " + caller);
4054        }
4055    }
4056
4057    void enforceShellRestriction(String restriction, int userHandle) {
4058        if (Binder.getCallingUid() == Process.SHELL_UID) {
4059            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
4060                throw new SecurityException("Shell does not have permission to access user "
4061                        + userHandle);
4062            }
4063        }
4064    }
4065
4066    @Override
4067    public int getFrontActivityScreenCompatMode() {
4068        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4069        synchronized (this) {
4070            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4071        }
4072    }
4073
4074    @Override
4075    public void setFrontActivityScreenCompatMode(int mode) {
4076        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4077                "setFrontActivityScreenCompatMode");
4078        synchronized (this) {
4079            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4080        }
4081    }
4082
4083    @Override
4084    public int getPackageScreenCompatMode(String packageName) {
4085        enforceNotIsolatedCaller("getPackageScreenCompatMode");
4086        synchronized (this) {
4087            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4088        }
4089    }
4090
4091    @Override
4092    public void setPackageScreenCompatMode(String packageName, int mode) {
4093        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4094                "setPackageScreenCompatMode");
4095        synchronized (this) {
4096            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4097        }
4098    }
4099
4100    @Override
4101    public boolean getPackageAskScreenCompat(String packageName) {
4102        enforceNotIsolatedCaller("getPackageAskScreenCompat");
4103        synchronized (this) {
4104            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4105        }
4106    }
4107
4108    @Override
4109    public void setPackageAskScreenCompat(String packageName, boolean ask) {
4110        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4111                "setPackageAskScreenCompat");
4112        synchronized (this) {
4113            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4114        }
4115    }
4116
4117    private boolean hasUsageStatsPermission(String callingPackage) {
4118        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4119                Binder.getCallingUid(), callingPackage);
4120        if (mode == AppOpsManager.MODE_DEFAULT) {
4121            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4122                    == PackageManager.PERMISSION_GRANTED;
4123        }
4124        return mode == AppOpsManager.MODE_ALLOWED;
4125    }
4126
4127    @Override
4128    public int getPackageProcessState(String packageName, String callingPackage) {
4129        if (!hasUsageStatsPermission(callingPackage)) {
4130            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
4131                    "getPackageProcessState");
4132        }
4133
4134        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4135        synchronized (this) {
4136            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4137                final ProcessRecord proc = mLruProcesses.get(i);
4138                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
4139                        || procState > proc.setProcState) {
4140                    boolean found = false;
4141                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
4142                        if (proc.pkgList.keyAt(j).equals(packageName)) {
4143                            procState = proc.setProcState;
4144                            found = true;
4145                        }
4146                    }
4147                    if (proc.pkgDeps != null && !found) {
4148                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
4149                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
4150                                procState = proc.setProcState;
4151                                break;
4152                            }
4153                        }
4154                    }
4155                }
4156            }
4157        }
4158        return procState;
4159    }
4160
4161    @Override
4162    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
4163        synchronized (this) {
4164            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4165            if (app == null) {
4166                return false;
4167            }
4168            if (app.trimMemoryLevel < level && app.thread != null &&
4169                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4170                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4171                try {
4172                    app.thread.scheduleTrimMemory(level);
4173                    app.trimMemoryLevel = level;
4174                    return true;
4175                } catch (RemoteException e) {
4176                    // Fallthrough to failure case.
4177                }
4178            }
4179        }
4180        return false;
4181    }
4182
4183    private void dispatchProcessesChanged() {
4184        int N;
4185        synchronized (this) {
4186            N = mPendingProcessChanges.size();
4187            if (mActiveProcessChanges.length < N) {
4188                mActiveProcessChanges = new ProcessChangeItem[N];
4189            }
4190            mPendingProcessChanges.toArray(mActiveProcessChanges);
4191            mPendingProcessChanges.clear();
4192            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4193                    "*** Delivering " + N + " process changes");
4194        }
4195
4196        int i = mProcessObservers.beginBroadcast();
4197        while (i > 0) {
4198            i--;
4199            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4200            if (observer != null) {
4201                try {
4202                    for (int j=0; j<N; j++) {
4203                        ProcessChangeItem item = mActiveProcessChanges[j];
4204                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4205                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4206                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4207                                    + item.uid + ": " + item.foregroundActivities);
4208                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4209                                    item.foregroundActivities);
4210                        }
4211                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4212                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4213                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4214                                    + ": " + item.processState);
4215                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4216                        }
4217                    }
4218                } catch (RemoteException e) {
4219                }
4220            }
4221        }
4222        mProcessObservers.finishBroadcast();
4223
4224        synchronized (this) {
4225            for (int j=0; j<N; j++) {
4226                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4227            }
4228        }
4229    }
4230
4231    private void dispatchProcessDied(int pid, int uid) {
4232        int i = mProcessObservers.beginBroadcast();
4233        while (i > 0) {
4234            i--;
4235            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4236            if (observer != null) {
4237                try {
4238                    observer.onProcessDied(pid, uid);
4239                } catch (RemoteException e) {
4240                }
4241            }
4242        }
4243        mProcessObservers.finishBroadcast();
4244    }
4245
4246    private void dispatchUidsChanged() {
4247        int N;
4248        synchronized (this) {
4249            N = mPendingUidChanges.size();
4250            if (mActiveUidChanges.length < N) {
4251                mActiveUidChanges = new UidRecord.ChangeItem[N];
4252            }
4253            for (int i=0; i<N; i++) {
4254                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4255                mActiveUidChanges[i] = change;
4256                if (change.uidRecord != null) {
4257                    change.uidRecord.pendingChange = null;
4258                    change.uidRecord = null;
4259                }
4260            }
4261            mPendingUidChanges.clear();
4262            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4263                    "*** Delivering " + N + " uid changes");
4264        }
4265
4266        if (mLocalPowerManager != null) {
4267            for (int j=0; j<N; j++) {
4268                UidRecord.ChangeItem item = mActiveUidChanges[j];
4269                if (item.change == UidRecord.CHANGE_GONE
4270                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
4271                    mLocalPowerManager.uidGone(item.uid);
4272                } else {
4273                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4274                }
4275            }
4276        }
4277
4278        int i = mUidObservers.beginBroadcast();
4279        while (i > 0) {
4280            i--;
4281            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4282            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4283            if (observer != null) {
4284                try {
4285                    for (int j=0; j<N; j++) {
4286                        UidRecord.ChangeItem item = mActiveUidChanges[j];
4287                        final int change = item.change;
4288                        UidRecord validateUid = null;
4289                        if (VALIDATE_UID_STATES && i == 0) {
4290                            validateUid = mValidateUids.get(item.uid);
4291                            if (validateUid == null && change != UidRecord.CHANGE_GONE
4292                                    && change != UidRecord.CHANGE_GONE_IDLE) {
4293                                validateUid = new UidRecord(item.uid);
4294                                mValidateUids.put(item.uid, validateUid);
4295                            }
4296                        }
4297                        if (change == UidRecord.CHANGE_IDLE
4298                                || change == UidRecord.CHANGE_GONE_IDLE) {
4299                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4300                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4301                                        "UID idle uid=" + item.uid);
4302                                observer.onUidIdle(item.uid);
4303                            }
4304                            if (VALIDATE_UID_STATES && i == 0) {
4305                                if (validateUid != null) {
4306                                    validateUid.idle = true;
4307                                }
4308                            }
4309                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4310                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4311                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4312                                        "UID active uid=" + item.uid);
4313                                observer.onUidActive(item.uid);
4314                            }
4315                            if (VALIDATE_UID_STATES && i == 0) {
4316                                validateUid.idle = false;
4317                            }
4318                        }
4319                        if (change == UidRecord.CHANGE_GONE
4320                                || change == UidRecord.CHANGE_GONE_IDLE) {
4321                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4322                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4323                                        "UID gone uid=" + item.uid);
4324                                observer.onUidGone(item.uid);
4325                            }
4326                            if (VALIDATE_UID_STATES && i == 0) {
4327                                if (validateUid != null) {
4328                                    mValidateUids.remove(item.uid);
4329                                }
4330                            }
4331                        } else {
4332                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4333                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4334                                        "UID CHANGED uid=" + item.uid
4335                                                + ": " + item.processState);
4336                                observer.onUidStateChanged(item.uid, item.processState);
4337                            }
4338                            if (VALIDATE_UID_STATES && i == 0) {
4339                                validateUid.curProcState = validateUid.setProcState
4340                                        = item.processState;
4341                            }
4342                        }
4343                    }
4344                } catch (RemoteException e) {
4345                }
4346            }
4347        }
4348        mUidObservers.finishBroadcast();
4349
4350        synchronized (this) {
4351            for (int j=0; j<N; j++) {
4352                mAvailUidChanges.add(mActiveUidChanges[j]);
4353            }
4354        }
4355    }
4356
4357    @Override
4358    public final int startActivity(IApplicationThread caller, String callingPackage,
4359            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4360            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4361        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4362                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4363                UserHandle.getCallingUserId());
4364    }
4365
4366    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4367        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4368        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4369                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4370                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4371
4372        // TODO: Switch to user app stacks here.
4373        String mimeType = intent.getType();
4374        final Uri data = intent.getData();
4375        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4376            mimeType = getProviderMimeType(data, userId);
4377        }
4378        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4379
4380        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4381        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4382                null, 0, 0, null, null, null, null, false, userId, container, null);
4383    }
4384
4385    @Override
4386    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4387            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4388            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4389        enforceNotIsolatedCaller("startActivity");
4390        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4391                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4392        // TODO: Switch to user app stacks here.
4393        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4394                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4395                profilerInfo, null, null, bOptions, false, userId, null, null);
4396    }
4397
4398    @Override
4399    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4400            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4401            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4402            int userId) {
4403
4404        // This is very dangerous -- it allows you to perform a start activity (including
4405        // permission grants) as any app that may launch one of your own activities.  So
4406        // we will only allow this to be done from activities that are part of the core framework,
4407        // and then only when they are running as the system.
4408        final ActivityRecord sourceRecord;
4409        final int targetUid;
4410        final String targetPackage;
4411        synchronized (this) {
4412            if (resultTo == null) {
4413                throw new SecurityException("Must be called from an activity");
4414            }
4415            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4416            if (sourceRecord == null) {
4417                throw new SecurityException("Called with bad activity token: " + resultTo);
4418            }
4419            if (!sourceRecord.info.packageName.equals("android")) {
4420                throw new SecurityException(
4421                        "Must be called from an activity that is declared in the android package");
4422            }
4423            if (sourceRecord.app == null) {
4424                throw new SecurityException("Called without a process attached to activity");
4425            }
4426            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4427                // This is still okay, as long as this activity is running under the
4428                // uid of the original calling activity.
4429                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4430                    throw new SecurityException(
4431                            "Calling activity in uid " + sourceRecord.app.uid
4432                                    + " must be system uid or original calling uid "
4433                                    + sourceRecord.launchedFromUid);
4434                }
4435            }
4436            if (ignoreTargetSecurity) {
4437                if (intent.getComponent() == null) {
4438                    throw new SecurityException(
4439                            "Component must be specified with ignoreTargetSecurity");
4440                }
4441                if (intent.getSelector() != null) {
4442                    throw new SecurityException(
4443                            "Selector not allowed with ignoreTargetSecurity");
4444                }
4445            }
4446            targetUid = sourceRecord.launchedFromUid;
4447            targetPackage = sourceRecord.launchedFromPackage;
4448        }
4449
4450        if (userId == UserHandle.USER_NULL) {
4451            userId = UserHandle.getUserId(sourceRecord.app.uid);
4452        }
4453
4454        // TODO: Switch to user app stacks here.
4455        try {
4456            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4457                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4458                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4459            return ret;
4460        } catch (SecurityException e) {
4461            // XXX need to figure out how to propagate to original app.
4462            // A SecurityException here is generally actually a fault of the original
4463            // calling activity (such as a fairly granting permissions), so propagate it
4464            // back to them.
4465            /*
4466            StringBuilder msg = new StringBuilder();
4467            msg.append("While launching");
4468            msg.append(intent.toString());
4469            msg.append(": ");
4470            msg.append(e.getMessage());
4471            */
4472            throw e;
4473        }
4474    }
4475
4476    @Override
4477    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4478            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4479            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4480        enforceNotIsolatedCaller("startActivityAndWait");
4481        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4482                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4483        WaitResult res = new WaitResult();
4484        // TODO: Switch to user app stacks here.
4485        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4486                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4487                bOptions, false, userId, null, null);
4488        return res;
4489    }
4490
4491    @Override
4492    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4493            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4494            int startFlags, Configuration config, Bundle bOptions, int userId) {
4495        enforceNotIsolatedCaller("startActivityWithConfig");
4496        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4497                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4498        // TODO: Switch to user app stacks here.
4499        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4500                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4501                null, null, config, bOptions, false, userId, null, null);
4502        return ret;
4503    }
4504
4505    @Override
4506    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4507            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4508            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4509            throws TransactionTooLargeException {
4510        enforceNotIsolatedCaller("startActivityIntentSender");
4511        // Refuse possible leaked file descriptors
4512        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4513            throw new IllegalArgumentException("File descriptors passed in Intent");
4514        }
4515
4516        IIntentSender sender = intent.getTarget();
4517        if (!(sender instanceof PendingIntentRecord)) {
4518            throw new IllegalArgumentException("Bad PendingIntent object");
4519        }
4520
4521        PendingIntentRecord pir = (PendingIntentRecord)sender;
4522
4523        synchronized (this) {
4524            // If this is coming from the currently resumed activity, it is
4525            // effectively saying that app switches are allowed at this point.
4526            final ActivityStack stack = getFocusedStack();
4527            if (stack.mResumedActivity != null &&
4528                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4529                mAppSwitchesAllowedTime = 0;
4530            }
4531        }
4532        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4533                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4534        return ret;
4535    }
4536
4537    @Override
4538    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4539            Intent intent, String resolvedType, IVoiceInteractionSession session,
4540            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4541            Bundle bOptions, int userId) {
4542        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4543                != PackageManager.PERMISSION_GRANTED) {
4544            String msg = "Permission Denial: startVoiceActivity() from pid="
4545                    + Binder.getCallingPid()
4546                    + ", uid=" + Binder.getCallingUid()
4547                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4548            Slog.w(TAG, msg);
4549            throw new SecurityException(msg);
4550        }
4551        if (session == null || interactor == null) {
4552            throw new NullPointerException("null session or interactor");
4553        }
4554        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4555                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4556        // TODO: Switch to user app stacks here.
4557        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4558                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4559                null, bOptions, false, userId, null, null);
4560    }
4561
4562    @Override
4563    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4564            throws RemoteException {
4565        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4566        synchronized (this) {
4567            ActivityRecord activity = getFocusedStack().topActivity();
4568            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4569                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4570            }
4571            if (mRunningVoice != null || activity.task.voiceSession != null
4572                    || activity.voiceSession != null) {
4573                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4574                return;
4575            }
4576            if (activity.pendingVoiceInteractionStart) {
4577                Slog.w(TAG, "Pending start of voice interaction already.");
4578                return;
4579            }
4580            activity.pendingVoiceInteractionStart = true;
4581        }
4582        LocalServices.getService(VoiceInteractionManagerInternal.class)
4583                .startLocalVoiceInteraction(callingActivity, options);
4584    }
4585
4586    @Override
4587    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4588        LocalServices.getService(VoiceInteractionManagerInternal.class)
4589                .stopLocalVoiceInteraction(callingActivity);
4590    }
4591
4592    @Override
4593    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4594        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4595                .supportsLocalVoiceInteraction();
4596    }
4597
4598    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4599            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4600        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4601        if (activityToCallback == null) return;
4602        activityToCallback.setVoiceSessionLocked(voiceSession);
4603
4604        // Inform the activity
4605        try {
4606            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4607                    voiceInteractor);
4608            long token = Binder.clearCallingIdentity();
4609            try {
4610                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4611            } finally {
4612                Binder.restoreCallingIdentity(token);
4613            }
4614            // TODO: VI Should we cache the activity so that it's easier to find later
4615            // rather than scan through all the stacks and activities?
4616        } catch (RemoteException re) {
4617            activityToCallback.clearVoiceSessionLocked();
4618            // TODO: VI Should this terminate the voice session?
4619        }
4620    }
4621
4622    @Override
4623    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4624        synchronized (this) {
4625            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4626                if (keepAwake) {
4627                    mVoiceWakeLock.acquire();
4628                } else {
4629                    mVoiceWakeLock.release();
4630                }
4631            }
4632        }
4633    }
4634
4635    @Override
4636    public boolean startNextMatchingActivity(IBinder callingActivity,
4637            Intent intent, Bundle bOptions) {
4638        // Refuse possible leaked file descriptors
4639        if (intent != null && intent.hasFileDescriptors() == true) {
4640            throw new IllegalArgumentException("File descriptors passed in Intent");
4641        }
4642        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4643
4644        synchronized (this) {
4645            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4646            if (r == null) {
4647                ActivityOptions.abort(options);
4648                return false;
4649            }
4650            if (r.app == null || r.app.thread == null) {
4651                // The caller is not running...  d'oh!
4652                ActivityOptions.abort(options);
4653                return false;
4654            }
4655            intent = new Intent(intent);
4656            // The caller is not allowed to change the data.
4657            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4658            // And we are resetting to find the next component...
4659            intent.setComponent(null);
4660
4661            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4662
4663            ActivityInfo aInfo = null;
4664            try {
4665                List<ResolveInfo> resolves =
4666                    AppGlobals.getPackageManager().queryIntentActivities(
4667                            intent, r.resolvedType,
4668                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4669                            UserHandle.getCallingUserId()).getList();
4670
4671                // Look for the original activity in the list...
4672                final int N = resolves != null ? resolves.size() : 0;
4673                for (int i=0; i<N; i++) {
4674                    ResolveInfo rInfo = resolves.get(i);
4675                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4676                            && rInfo.activityInfo.name.equals(r.info.name)) {
4677                        // We found the current one...  the next matching is
4678                        // after it.
4679                        i++;
4680                        if (i<N) {
4681                            aInfo = resolves.get(i).activityInfo;
4682                        }
4683                        if (debug) {
4684                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4685                                    + "/" + r.info.name);
4686                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4687                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4688                        }
4689                        break;
4690                    }
4691                }
4692            } catch (RemoteException e) {
4693            }
4694
4695            if (aInfo == null) {
4696                // Nobody who is next!
4697                ActivityOptions.abort(options);
4698                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4699                return false;
4700            }
4701
4702            intent.setComponent(new ComponentName(
4703                    aInfo.applicationInfo.packageName, aInfo.name));
4704            intent.setFlags(intent.getFlags()&~(
4705                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4706                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4707                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4708                    Intent.FLAG_ACTIVITY_NEW_TASK));
4709
4710            // Okay now we need to start the new activity, replacing the
4711            // currently running activity.  This is a little tricky because
4712            // we want to start the new one as if the current one is finished,
4713            // but not finish the current one first so that there is no flicker.
4714            // And thus...
4715            final boolean wasFinishing = r.finishing;
4716            r.finishing = true;
4717
4718            // Propagate reply information over to the new activity.
4719            final ActivityRecord resultTo = r.resultTo;
4720            final String resultWho = r.resultWho;
4721            final int requestCode = r.requestCode;
4722            r.resultTo = null;
4723            if (resultTo != null) {
4724                resultTo.removeResultsLocked(r, resultWho, requestCode);
4725            }
4726
4727            final long origId = Binder.clearCallingIdentity();
4728            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4729                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4730                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4731                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4732                    false, false, null, null, null);
4733            Binder.restoreCallingIdentity(origId);
4734
4735            r.finishing = wasFinishing;
4736            if (res != ActivityManager.START_SUCCESS) {
4737                return false;
4738            }
4739            return true;
4740        }
4741    }
4742
4743    @Override
4744    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4745        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4746            String msg = "Permission Denial: startActivityFromRecents called without " +
4747                    START_TASKS_FROM_RECENTS;
4748            Slog.w(TAG, msg);
4749            throw new SecurityException(msg);
4750        }
4751        final long origId = Binder.clearCallingIdentity();
4752        try {
4753            synchronized (this) {
4754                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4755            }
4756        } finally {
4757            Binder.restoreCallingIdentity(origId);
4758        }
4759    }
4760
4761    final int startActivityInPackage(int uid, String callingPackage,
4762            Intent intent, String resolvedType, IBinder resultTo,
4763            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4764            IActivityContainer container, TaskRecord inTask) {
4765
4766        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4767                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4768
4769        // TODO: Switch to user app stacks here.
4770        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4771                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4772                null, null, null, bOptions, false, userId, container, inTask);
4773        return ret;
4774    }
4775
4776    @Override
4777    public final int startActivities(IApplicationThread caller, String callingPackage,
4778            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4779            int userId) {
4780        enforceNotIsolatedCaller("startActivities");
4781        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4782                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4783        // TODO: Switch to user app stacks here.
4784        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4785                resolvedTypes, resultTo, bOptions, userId);
4786        return ret;
4787    }
4788
4789    final int startActivitiesInPackage(int uid, String callingPackage,
4790            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4791            Bundle bOptions, int userId) {
4792
4793        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4794                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4795        // TODO: Switch to user app stacks here.
4796        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4797                resultTo, bOptions, userId);
4798        return ret;
4799    }
4800
4801    @Override
4802    public void reportActivityFullyDrawn(IBinder token) {
4803        synchronized (this) {
4804            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4805            if (r == null) {
4806                return;
4807            }
4808            r.reportFullyDrawnLocked();
4809        }
4810    }
4811
4812    @Override
4813    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4814        synchronized (this) {
4815            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4816            if (r == null) {
4817                return;
4818            }
4819            TaskRecord task = r.task;
4820            if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4821                // Fixed screen orientation isn't supported when activities aren't in full screen
4822                // mode.
4823                return;
4824            }
4825            final long origId = Binder.clearCallingIdentity();
4826            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4827            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4828                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4829            if (config != null) {
4830                r.frozenBeforeDestroy = true;
4831                if (!updateConfigurationLocked(config, r, false)) {
4832                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
4833                }
4834            }
4835            Binder.restoreCallingIdentity(origId);
4836        }
4837    }
4838
4839    @Override
4840    public int getRequestedOrientation(IBinder token) {
4841        synchronized (this) {
4842            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4843            if (r == null) {
4844                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4845            }
4846            return mWindowManager.getAppOrientation(r.appToken);
4847        }
4848    }
4849
4850    /**
4851     * This is the internal entry point for handling Activity.finish().
4852     *
4853     * @param token The Binder token referencing the Activity we want to finish.
4854     * @param resultCode Result code, if any, from this Activity.
4855     * @param resultData Result data (Intent), if any, from this Activity.
4856     * @param finishTask Whether to finish the task associated with this Activity.
4857     *
4858     * @return Returns true if the activity successfully finished, or false if it is still running.
4859     */
4860    @Override
4861    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4862            int finishTask) {
4863        // Refuse possible leaked file descriptors
4864        if (resultData != null && resultData.hasFileDescriptors() == true) {
4865            throw new IllegalArgumentException("File descriptors passed in Intent");
4866        }
4867
4868        synchronized(this) {
4869            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4870            if (r == null) {
4871                return true;
4872            }
4873            // Keep track of the root activity of the task before we finish it
4874            TaskRecord tr = r.task;
4875            ActivityRecord rootR = tr.getRootActivity();
4876            if (rootR == null) {
4877                Slog.w(TAG, "Finishing task with all activities already finished");
4878            }
4879            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4880            // finish.
4881            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4882                    mStackSupervisor.isLastLockedTask(tr)) {
4883                Slog.i(TAG, "Not finishing task in lock task mode");
4884                mStackSupervisor.showLockTaskToast();
4885                return false;
4886            }
4887            if (mController != null) {
4888                // Find the first activity that is not finishing.
4889                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4890                if (next != null) {
4891                    // ask watcher if this is allowed
4892                    boolean resumeOK = true;
4893                    try {
4894                        resumeOK = mController.activityResuming(next.packageName);
4895                    } catch (RemoteException e) {
4896                        mController = null;
4897                        Watchdog.getInstance().setActivityController(null);
4898                    }
4899
4900                    if (!resumeOK) {
4901                        Slog.i(TAG, "Not finishing activity because controller resumed");
4902                        return false;
4903                    }
4904                }
4905            }
4906            final long origId = Binder.clearCallingIdentity();
4907            try {
4908                boolean res;
4909                final boolean finishWithRootActivity =
4910                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4911                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4912                        || (finishWithRootActivity && r == rootR)) {
4913                    // If requested, remove the task that is associated to this activity only if it
4914                    // was the root activity in the task. The result code and data is ignored
4915                    // because we don't support returning them across task boundaries. Also, to
4916                    // keep backwards compatibility we remove the task from recents when finishing
4917                    // task with root activity.
4918                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4919                    if (!res) {
4920                        Slog.i(TAG, "Removing task failed to finish activity");
4921                    }
4922                } else {
4923                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4924                            resultData, "app-request", true);
4925                    if (!res) {
4926                        Slog.i(TAG, "Failed to finish by app-request");
4927                    }
4928                }
4929                return res;
4930            } finally {
4931                Binder.restoreCallingIdentity(origId);
4932            }
4933        }
4934    }
4935
4936    @Override
4937    public final void finishHeavyWeightApp() {
4938        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4939                != PackageManager.PERMISSION_GRANTED) {
4940            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4941                    + Binder.getCallingPid()
4942                    + ", uid=" + Binder.getCallingUid()
4943                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4944            Slog.w(TAG, msg);
4945            throw new SecurityException(msg);
4946        }
4947
4948        synchronized(this) {
4949            if (mHeavyWeightProcess == null) {
4950                return;
4951            }
4952
4953            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4954            for (int i = 0; i < activities.size(); i++) {
4955                ActivityRecord r = activities.get(i);
4956                if (!r.finishing && r.isInStackLocked()) {
4957                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4958                            null, "finish-heavy", true);
4959                }
4960            }
4961
4962            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4963                    mHeavyWeightProcess.userId, 0));
4964            mHeavyWeightProcess = null;
4965        }
4966    }
4967
4968    @Override
4969    public void crashApplication(int uid, int initialPid, String packageName,
4970            String message) {
4971        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4972                != PackageManager.PERMISSION_GRANTED) {
4973            String msg = "Permission Denial: crashApplication() from pid="
4974                    + Binder.getCallingPid()
4975                    + ", uid=" + Binder.getCallingUid()
4976                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4977            Slog.w(TAG, msg);
4978            throw new SecurityException(msg);
4979        }
4980
4981        synchronized(this) {
4982            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4983        }
4984    }
4985
4986    @Override
4987    public final void finishSubActivity(IBinder token, String resultWho,
4988            int requestCode) {
4989        synchronized(this) {
4990            final long origId = Binder.clearCallingIdentity();
4991            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4992            if (r != null) {
4993                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4994            }
4995            Binder.restoreCallingIdentity(origId);
4996        }
4997    }
4998
4999    @Override
5000    public boolean finishActivityAffinity(IBinder token) {
5001        synchronized(this) {
5002            final long origId = Binder.clearCallingIdentity();
5003            try {
5004                ActivityRecord r = ActivityRecord.isInStackLocked(token);
5005                if (r == null) {
5006                    return false;
5007                }
5008
5009                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
5010                // can finish.
5011                final TaskRecord task = r.task;
5012                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
5013                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
5014                    mStackSupervisor.showLockTaskToast();
5015                    return false;
5016                }
5017                return task.stack.finishActivityAffinityLocked(r);
5018            } finally {
5019                Binder.restoreCallingIdentity(origId);
5020            }
5021        }
5022    }
5023
5024    @Override
5025    public void finishVoiceTask(IVoiceInteractionSession session) {
5026        synchronized (this) {
5027            final long origId = Binder.clearCallingIdentity();
5028            try {
5029                // TODO: VI Consider treating local voice interactions and voice tasks
5030                // differently here
5031                mStackSupervisor.finishVoiceTask(session);
5032            } finally {
5033                Binder.restoreCallingIdentity(origId);
5034            }
5035        }
5036
5037    }
5038
5039    @Override
5040    public boolean releaseActivityInstance(IBinder token) {
5041        synchronized(this) {
5042            final long origId = Binder.clearCallingIdentity();
5043            try {
5044                ActivityRecord r = ActivityRecord.isInStackLocked(token);
5045                if (r == null) {
5046                    return false;
5047                }
5048                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
5049            } finally {
5050                Binder.restoreCallingIdentity(origId);
5051            }
5052        }
5053    }
5054
5055    @Override
5056    public void releaseSomeActivities(IApplicationThread appInt) {
5057        synchronized(this) {
5058            final long origId = Binder.clearCallingIdentity();
5059            try {
5060                ProcessRecord app = getRecordForAppLocked(appInt);
5061                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5062            } finally {
5063                Binder.restoreCallingIdentity(origId);
5064            }
5065        }
5066    }
5067
5068    @Override
5069    public boolean willActivityBeVisible(IBinder token) {
5070        synchronized(this) {
5071            ActivityStack stack = ActivityRecord.getStackLocked(token);
5072            if (stack != null) {
5073                return stack.willActivityBeVisibleLocked(token);
5074            }
5075            return false;
5076        }
5077    }
5078
5079    @Override
5080    public void overridePendingTransition(IBinder token, String packageName,
5081            int enterAnim, int exitAnim) {
5082        synchronized(this) {
5083            ActivityRecord self = ActivityRecord.isInStackLocked(token);
5084            if (self == null) {
5085                return;
5086            }
5087
5088            final long origId = Binder.clearCallingIdentity();
5089
5090            if (self.state == ActivityState.RESUMED
5091                    || self.state == ActivityState.PAUSING) {
5092                mWindowManager.overridePendingAppTransition(packageName,
5093                        enterAnim, exitAnim, null);
5094            }
5095
5096            Binder.restoreCallingIdentity(origId);
5097        }
5098    }
5099
5100    /**
5101     * Main function for removing an existing process from the activity manager
5102     * as a result of that process going away.  Clears out all connections
5103     * to the process.
5104     */
5105    private final void handleAppDiedLocked(ProcessRecord app,
5106            boolean restarting, boolean allowRestart) {
5107        int pid = app.pid;
5108        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5109                false /*replacingPid*/);
5110        if (!kept && !restarting) {
5111            removeLruProcessLocked(app);
5112            if (pid > 0) {
5113                ProcessList.remove(pid);
5114            }
5115        }
5116
5117        if (mProfileProc == app) {
5118            clearProfilerLocked();
5119        }
5120
5121        // Remove this application's activities from active lists.
5122        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5123
5124        app.activities.clear();
5125
5126        if (app.instrumentationClass != null) {
5127            Slog.w(TAG, "Crash of app " + app.processName
5128                  + " running instrumentation " + app.instrumentationClass);
5129            Bundle info = new Bundle();
5130            info.putString("shortMsg", "Process crashed.");
5131            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5132        }
5133
5134        if (!restarting && hasVisibleActivities
5135                && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5136            // If there was nothing to resume, and we are not already restarting this process, but
5137            // there is a visible activity that is hosted by the process...  then make sure all
5138            // visible activities are running, taking care of restarting this process.
5139            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5140        }
5141    }
5142
5143    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5144        IBinder threadBinder = thread.asBinder();
5145        // Find the application record.
5146        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5147            ProcessRecord rec = mLruProcesses.get(i);
5148            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5149                return i;
5150            }
5151        }
5152        return -1;
5153    }
5154
5155    final ProcessRecord getRecordForAppLocked(
5156            IApplicationThread thread) {
5157        if (thread == null) {
5158            return null;
5159        }
5160
5161        int appIndex = getLRURecordIndexForAppLocked(thread);
5162        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
5163    }
5164
5165    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5166        // If there are no longer any background processes running,
5167        // and the app that died was not running instrumentation,
5168        // then tell everyone we are now low on memory.
5169        boolean haveBg = false;
5170        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5171            ProcessRecord rec = mLruProcesses.get(i);
5172            if (rec.thread != null
5173                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5174                haveBg = true;
5175                break;
5176            }
5177        }
5178
5179        if (!haveBg) {
5180            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5181            if (doReport) {
5182                long now = SystemClock.uptimeMillis();
5183                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5184                    doReport = false;
5185                } else {
5186                    mLastMemUsageReportTime = now;
5187                }
5188            }
5189            final ArrayList<ProcessMemInfo> memInfos
5190                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5191            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5192            long now = SystemClock.uptimeMillis();
5193            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5194                ProcessRecord rec = mLruProcesses.get(i);
5195                if (rec == dyingProc || rec.thread == null) {
5196                    continue;
5197                }
5198                if (doReport) {
5199                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5200                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5201                }
5202                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5203                    // The low memory report is overriding any current
5204                    // state for a GC request.  Make sure to do
5205                    // heavy/important/visible/foreground processes first.
5206                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5207                        rec.lastRequestedGc = 0;
5208                    } else {
5209                        rec.lastRequestedGc = rec.lastLowMemory;
5210                    }
5211                    rec.reportLowMemory = true;
5212                    rec.lastLowMemory = now;
5213                    mProcessesToGc.remove(rec);
5214                    addProcessToGcListLocked(rec);
5215                }
5216            }
5217            if (doReport) {
5218                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5219                mHandler.sendMessage(msg);
5220            }
5221            scheduleAppGcsLocked();
5222        }
5223    }
5224
5225    final void appDiedLocked(ProcessRecord app) {
5226       appDiedLocked(app, app.pid, app.thread, false);
5227    }
5228
5229    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5230            boolean fromBinderDied) {
5231        // First check if this ProcessRecord is actually active for the pid.
5232        synchronized (mPidsSelfLocked) {
5233            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5234            if (curProc != app) {
5235                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5236                return;
5237            }
5238        }
5239
5240        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5241        synchronized (stats) {
5242            stats.noteProcessDiedLocked(app.info.uid, pid);
5243        }
5244
5245        if (!app.killed) {
5246            if (!fromBinderDied) {
5247                Process.killProcessQuiet(pid);
5248            }
5249            killProcessGroup(app.uid, pid);
5250            app.killed = true;
5251        }
5252
5253        // Clean up already done if the process has been re-started.
5254        if (app.pid == pid && app.thread != null &&
5255                app.thread.asBinder() == thread.asBinder()) {
5256            boolean doLowMem = app.instrumentationClass == null;
5257            boolean doOomAdj = doLowMem;
5258            if (!app.killedByAm) {
5259                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5260                        + ") has died");
5261                mAllowLowerMemLevel = true;
5262            } else {
5263                // Note that we always want to do oom adj to update our state with the
5264                // new number of procs.
5265                mAllowLowerMemLevel = false;
5266                doLowMem = false;
5267            }
5268            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5269            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5270                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5271            handleAppDiedLocked(app, false, true);
5272
5273            if (doOomAdj) {
5274                updateOomAdjLocked();
5275            }
5276            if (doLowMem) {
5277                doLowMemReportIfNeededLocked(app);
5278            }
5279        } else if (app.pid != pid) {
5280            // A new process has already been started.
5281            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5282                    + ") has died and restarted (pid " + app.pid + ").");
5283            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5284        } else if (DEBUG_PROCESSES) {
5285            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5286                    + thread.asBinder());
5287        }
5288    }
5289
5290    /**
5291     * If a stack trace dump file is configured, dump process stack traces.
5292     * @param clearTraces causes the dump file to be erased prior to the new
5293     *    traces being written, if true; when false, the new traces will be
5294     *    appended to any existing file content.
5295     * @param firstPids of dalvik VM processes to dump stack traces for first
5296     * @param lastPids of dalvik VM processes to dump stack traces for last
5297     * @param nativeProcs optional list of native process names to dump stack crawls
5298     * @return file containing stack traces, or null if no dump file is configured
5299     */
5300    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5301            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5302        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5303        if (tracesPath == null || tracesPath.length() == 0) {
5304            return null;
5305        }
5306
5307        File tracesFile = new File(tracesPath);
5308        try {
5309            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5310            tracesFile.createNewFile();
5311            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5312        } catch (IOException e) {
5313            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5314            return null;
5315        }
5316
5317        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5318        return tracesFile;
5319    }
5320
5321    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5322            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5323        // Use a FileObserver to detect when traces finish writing.
5324        // The order of traces is considered important to maintain for legibility.
5325        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5326            @Override
5327            public synchronized void onEvent(int event, String path) { notify(); }
5328        };
5329
5330        try {
5331            observer.startWatching();
5332
5333            // First collect all of the stacks of the most important pids.
5334            if (firstPids != null) {
5335                try {
5336                    int num = firstPids.size();
5337                    for (int i = 0; i < num; i++) {
5338                        synchronized (observer) {
5339                            if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5340                                    + firstPids.get(i));
5341                            final long sime = SystemClock.elapsedRealtime();
5342                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5343                            observer.wait(1000);  // Wait for write-close, give up after 1 sec
5344                            if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5345                                    + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5346                        }
5347                    }
5348                } catch (InterruptedException e) {
5349                    Slog.wtf(TAG, e);
5350                }
5351            }
5352
5353            // Next collect the stacks of the native pids
5354            if (nativeProcs != null) {
5355                int[] pids = Process.getPidsForCommands(nativeProcs);
5356                if (pids != null) {
5357                    for (int pid : pids) {
5358                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5359                        final long sime = SystemClock.elapsedRealtime();
5360                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5361                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5362                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5363                    }
5364                }
5365            }
5366
5367            // Lastly, measure CPU usage.
5368            if (processCpuTracker != null) {
5369                processCpuTracker.init();
5370                System.gc();
5371                processCpuTracker.update();
5372                try {
5373                    synchronized (processCpuTracker) {
5374                        processCpuTracker.wait(500); // measure over 1/2 second.
5375                    }
5376                } catch (InterruptedException e) {
5377                }
5378                processCpuTracker.update();
5379
5380                // We'll take the stack crawls of just the top apps using CPU.
5381                final int N = processCpuTracker.countWorkingStats();
5382                int numProcs = 0;
5383                for (int i=0; i<N && numProcs<5; i++) {
5384                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5385                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5386                        numProcs++;
5387                        try {
5388                            synchronized (observer) {
5389                                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5390                                        + stats.pid);
5391                                final long stime = SystemClock.elapsedRealtime();
5392                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5393                                observer.wait(1000);  // Wait for write-close, give up after 1 sec
5394                                if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5395                                        + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5396                            }
5397                        } catch (InterruptedException e) {
5398                            Slog.wtf(TAG, e);
5399                        }
5400                    } else if (DEBUG_ANR) {
5401                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5402                                + stats.pid);
5403                    }
5404                }
5405            }
5406        } finally {
5407            observer.stopWatching();
5408        }
5409    }
5410
5411    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5412        if (true || IS_USER_BUILD) {
5413            return;
5414        }
5415        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5416        if (tracesPath == null || tracesPath.length() == 0) {
5417            return;
5418        }
5419
5420        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5421        StrictMode.allowThreadDiskWrites();
5422        try {
5423            final File tracesFile = new File(tracesPath);
5424            final File tracesDir = tracesFile.getParentFile();
5425            final File tracesTmp = new File(tracesDir, "__tmp__");
5426            try {
5427                if (tracesFile.exists()) {
5428                    tracesTmp.delete();
5429                    tracesFile.renameTo(tracesTmp);
5430                }
5431                StringBuilder sb = new StringBuilder();
5432                Time tobj = new Time();
5433                tobj.set(System.currentTimeMillis());
5434                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5435                sb.append(": ");
5436                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5437                sb.append(" since ");
5438                sb.append(msg);
5439                FileOutputStream fos = new FileOutputStream(tracesFile);
5440                fos.write(sb.toString().getBytes());
5441                if (app == null) {
5442                    fos.write("\n*** No application process!".getBytes());
5443                }
5444                fos.close();
5445                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5446            } catch (IOException e) {
5447                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5448                return;
5449            }
5450
5451            if (app != null) {
5452                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5453                firstPids.add(app.pid);
5454                dumpStackTraces(tracesPath, firstPids, null, null, null);
5455            }
5456
5457            File lastTracesFile = null;
5458            File curTracesFile = null;
5459            for (int i=9; i>=0; i--) {
5460                String name = String.format(Locale.US, "slow%02d.txt", i);
5461                curTracesFile = new File(tracesDir, name);
5462                if (curTracesFile.exists()) {
5463                    if (lastTracesFile != null) {
5464                        curTracesFile.renameTo(lastTracesFile);
5465                    } else {
5466                        curTracesFile.delete();
5467                    }
5468                }
5469                lastTracesFile = curTracesFile;
5470            }
5471            tracesFile.renameTo(curTracesFile);
5472            if (tracesTmp.exists()) {
5473                tracesTmp.renameTo(tracesFile);
5474            }
5475        } finally {
5476            StrictMode.setThreadPolicy(oldPolicy);
5477        }
5478    }
5479
5480    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5481        if (!mLaunchWarningShown) {
5482            mLaunchWarningShown = true;
5483            mUiHandler.post(new Runnable() {
5484                @Override
5485                public void run() {
5486                    synchronized (ActivityManagerService.this) {
5487                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5488                        d.show();
5489                        mUiHandler.postDelayed(new Runnable() {
5490                            @Override
5491                            public void run() {
5492                                synchronized (ActivityManagerService.this) {
5493                                    d.dismiss();
5494                                    mLaunchWarningShown = false;
5495                                }
5496                            }
5497                        }, 4000);
5498                    }
5499                }
5500            });
5501        }
5502    }
5503
5504    @Override
5505    public boolean clearApplicationUserData(final String packageName,
5506            final IPackageDataObserver observer, int userId) {
5507        enforceNotIsolatedCaller("clearApplicationUserData");
5508        int uid = Binder.getCallingUid();
5509        int pid = Binder.getCallingPid();
5510        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5511                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5512
5513
5514        long callingId = Binder.clearCallingIdentity();
5515        try {
5516            IPackageManager pm = AppGlobals.getPackageManager();
5517            int pkgUid = -1;
5518            synchronized(this) {
5519                if (getPackageManagerInternalLocked().isPackageDataProtected(
5520                        userId, packageName)) {
5521                    throw new SecurityException(
5522                            "Cannot clear data for a protected package: " + packageName);
5523                }
5524
5525                try {
5526                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5527                } catch (RemoteException e) {
5528                }
5529                if (pkgUid == -1) {
5530                    Slog.w(TAG, "Invalid packageName: " + packageName);
5531                    if (observer != null) {
5532                        try {
5533                            observer.onRemoveCompleted(packageName, false);
5534                        } catch (RemoteException e) {
5535                            Slog.i(TAG, "Observer no longer exists.");
5536                        }
5537                    }
5538                    return false;
5539                }
5540                if (uid == pkgUid || checkComponentPermission(
5541                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5542                        pid, uid, -1, true)
5543                        == PackageManager.PERMISSION_GRANTED) {
5544                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5545                } else {
5546                    throw new SecurityException("PID " + pid + " does not have permission "
5547                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5548                                    + " of package " + packageName);
5549                }
5550
5551                // Remove all tasks match the cleared application package and user
5552                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5553                    final TaskRecord tr = mRecentTasks.get(i);
5554                    final String taskPackageName =
5555                            tr.getBaseIntent().getComponent().getPackageName();
5556                    if (tr.userId != userId) continue;
5557                    if (!taskPackageName.equals(packageName)) continue;
5558                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5559                }
5560            }
5561
5562            final int pkgUidF = pkgUid;
5563            final int userIdF = userId;
5564            final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5565                @Override
5566                public void onRemoveCompleted(String packageName, boolean succeeded)
5567                        throws RemoteException {
5568                    synchronized (ActivityManagerService.this) {
5569                        finishForceStopPackageLocked(packageName, pkgUidF);
5570                    }
5571
5572                    final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5573                            Uri.fromParts("package", packageName, null));
5574                    intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5575                    intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5576                    broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5577                            null, null, 0, null, null, null, null, false, false, userIdF);
5578
5579                    if (observer != null) {
5580                        observer.onRemoveCompleted(packageName, succeeded);
5581                    }
5582                }
5583            };
5584
5585            try {
5586                // Clear application user data
5587                pm.clearApplicationUserData(packageName, localObserver, userId);
5588
5589                synchronized(this) {
5590                    // Remove all permissions granted from/to this package
5591                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5592                }
5593
5594                // Remove all zen rules created by this package; revoke it's zen access.
5595                INotificationManager inm = NotificationManager.getService();
5596                inm.removeAutomaticZenRules(packageName);
5597                inm.setNotificationPolicyAccessGranted(packageName, false);
5598
5599            } catch (RemoteException e) {
5600            }
5601        } finally {
5602            Binder.restoreCallingIdentity(callingId);
5603        }
5604        return true;
5605    }
5606
5607    @Override
5608    public void killBackgroundProcesses(final String packageName, int userId) {
5609        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5610                != PackageManager.PERMISSION_GRANTED &&
5611                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5612                        != PackageManager.PERMISSION_GRANTED) {
5613            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5614                    + Binder.getCallingPid()
5615                    + ", uid=" + Binder.getCallingUid()
5616                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5617            Slog.w(TAG, msg);
5618            throw new SecurityException(msg);
5619        }
5620
5621        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5622                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5623        long callingId = Binder.clearCallingIdentity();
5624        try {
5625            IPackageManager pm = AppGlobals.getPackageManager();
5626            synchronized(this) {
5627                int appId = -1;
5628                try {
5629                    appId = UserHandle.getAppId(
5630                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5631                } catch (RemoteException e) {
5632                }
5633                if (appId == -1) {
5634                    Slog.w(TAG, "Invalid packageName: " + packageName);
5635                    return;
5636                }
5637                killPackageProcessesLocked(packageName, appId, userId,
5638                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5639            }
5640        } finally {
5641            Binder.restoreCallingIdentity(callingId);
5642        }
5643    }
5644
5645    @Override
5646    public void killAllBackgroundProcesses() {
5647        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5648                != PackageManager.PERMISSION_GRANTED) {
5649            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5650                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5651                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5652            Slog.w(TAG, msg);
5653            throw new SecurityException(msg);
5654        }
5655
5656        final long callingId = Binder.clearCallingIdentity();
5657        try {
5658            synchronized (this) {
5659                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5660                final int NP = mProcessNames.getMap().size();
5661                for (int ip = 0; ip < NP; ip++) {
5662                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5663                    final int NA = apps.size();
5664                    for (int ia = 0; ia < NA; ia++) {
5665                        final ProcessRecord app = apps.valueAt(ia);
5666                        if (app.persistent) {
5667                            // We don't kill persistent processes.
5668                            continue;
5669                        }
5670                        if (app.removed) {
5671                            procs.add(app);
5672                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5673                            app.removed = true;
5674                            procs.add(app);
5675                        }
5676                    }
5677                }
5678
5679                final int N = procs.size();
5680                for (int i = 0; i < N; i++) {
5681                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5682                }
5683
5684                mAllowLowerMemLevel = true;
5685
5686                updateOomAdjLocked();
5687                doLowMemReportIfNeededLocked(null);
5688            }
5689        } finally {
5690            Binder.restoreCallingIdentity(callingId);
5691        }
5692    }
5693
5694    /**
5695     * Kills all background processes, except those matching any of the
5696     * specified properties.
5697     *
5698     * @param minTargetSdk the target SDK version at or above which to preserve
5699     *                     processes, or {@code -1} to ignore the target SDK
5700     * @param maxProcState the process state at or below which to preserve
5701     *                     processes, or {@code -1} to ignore the process state
5702     */
5703    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5704        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5705                != PackageManager.PERMISSION_GRANTED) {
5706            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5707                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5708                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5709            Slog.w(TAG, msg);
5710            throw new SecurityException(msg);
5711        }
5712
5713        final long callingId = Binder.clearCallingIdentity();
5714        try {
5715            synchronized (this) {
5716                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5717                final int NP = mProcessNames.getMap().size();
5718                for (int ip = 0; ip < NP; ip++) {
5719                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5720                    final int NA = apps.size();
5721                    for (int ia = 0; ia < NA; ia++) {
5722                        final ProcessRecord app = apps.valueAt(ia);
5723                        if (app.removed) {
5724                            procs.add(app);
5725                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5726                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5727                            app.removed = true;
5728                            procs.add(app);
5729                        }
5730                    }
5731                }
5732
5733                final int N = procs.size();
5734                for (int i = 0; i < N; i++) {
5735                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5736                }
5737            }
5738        } finally {
5739            Binder.restoreCallingIdentity(callingId);
5740        }
5741    }
5742
5743    @Override
5744    public void forceStopPackage(final String packageName, int userId) {
5745        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5746                != PackageManager.PERMISSION_GRANTED) {
5747            String msg = "Permission Denial: forceStopPackage() from pid="
5748                    + Binder.getCallingPid()
5749                    + ", uid=" + Binder.getCallingUid()
5750                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5751            Slog.w(TAG, msg);
5752            throw new SecurityException(msg);
5753        }
5754        final int callingPid = Binder.getCallingPid();
5755        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5756                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5757        long callingId = Binder.clearCallingIdentity();
5758        try {
5759            IPackageManager pm = AppGlobals.getPackageManager();
5760            synchronized(this) {
5761                int[] users = userId == UserHandle.USER_ALL
5762                        ? mUserController.getUsers() : new int[] { userId };
5763                for (int user : users) {
5764                    int pkgUid = -1;
5765                    try {
5766                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5767                                user);
5768                    } catch (RemoteException e) {
5769                    }
5770                    if (pkgUid == -1) {
5771                        Slog.w(TAG, "Invalid packageName: " + packageName);
5772                        continue;
5773                    }
5774                    try {
5775                        pm.setPackageStoppedState(packageName, true, user);
5776                    } catch (RemoteException e) {
5777                    } catch (IllegalArgumentException e) {
5778                        Slog.w(TAG, "Failed trying to unstop package "
5779                                + packageName + ": " + e);
5780                    }
5781                    if (mUserController.isUserRunningLocked(user, 0)) {
5782                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5783                        finishForceStopPackageLocked(packageName, pkgUid);
5784                    }
5785                }
5786            }
5787        } finally {
5788            Binder.restoreCallingIdentity(callingId);
5789        }
5790    }
5791
5792    @Override
5793    public void addPackageDependency(String packageName) {
5794        synchronized (this) {
5795            int callingPid = Binder.getCallingPid();
5796            if (callingPid == Process.myPid()) {
5797                //  Yeah, um, no.
5798                return;
5799            }
5800            ProcessRecord proc;
5801            synchronized (mPidsSelfLocked) {
5802                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5803            }
5804            if (proc != null) {
5805                if (proc.pkgDeps == null) {
5806                    proc.pkgDeps = new ArraySet<String>(1);
5807                }
5808                proc.pkgDeps.add(packageName);
5809            }
5810        }
5811    }
5812
5813    /*
5814     * The pkg name and app id have to be specified.
5815     */
5816    @Override
5817    public void killApplication(String pkg, int appId, int userId, String reason) {
5818        if (pkg == null) {
5819            return;
5820        }
5821        // Make sure the uid is valid.
5822        if (appId < 0) {
5823            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5824            return;
5825        }
5826        int callerUid = Binder.getCallingUid();
5827        // Only the system server can kill an application
5828        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5829            // Post an aysnc message to kill the application
5830            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5831            msg.arg1 = appId;
5832            msg.arg2 = userId;
5833            Bundle bundle = new Bundle();
5834            bundle.putString("pkg", pkg);
5835            bundle.putString("reason", reason);
5836            msg.obj = bundle;
5837            mHandler.sendMessage(msg);
5838        } else {
5839            throw new SecurityException(callerUid + " cannot kill pkg: " +
5840                    pkg);
5841        }
5842    }
5843
5844    @Override
5845    public void closeSystemDialogs(String reason) {
5846        enforceNotIsolatedCaller("closeSystemDialogs");
5847
5848        final int pid = Binder.getCallingPid();
5849        final int uid = Binder.getCallingUid();
5850        final long origId = Binder.clearCallingIdentity();
5851        try {
5852            synchronized (this) {
5853                // Only allow this from foreground processes, so that background
5854                // applications can't abuse it to prevent system UI from being shown.
5855                if (uid >= Process.FIRST_APPLICATION_UID) {
5856                    ProcessRecord proc;
5857                    synchronized (mPidsSelfLocked) {
5858                        proc = mPidsSelfLocked.get(pid);
5859                    }
5860                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5861                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5862                                + " from background process " + proc);
5863                        return;
5864                    }
5865                }
5866                closeSystemDialogsLocked(reason);
5867            }
5868        } finally {
5869            Binder.restoreCallingIdentity(origId);
5870        }
5871    }
5872
5873    void closeSystemDialogsLocked(String reason) {
5874        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5875        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5876                | Intent.FLAG_RECEIVER_FOREGROUND);
5877        if (reason != null) {
5878            intent.putExtra("reason", reason);
5879        }
5880        mWindowManager.closeSystemDialogs(reason);
5881
5882        mStackSupervisor.closeSystemDialogsLocked();
5883
5884        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5885                AppOpsManager.OP_NONE, null, false, false,
5886                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5887    }
5888
5889    @Override
5890    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5891        enforceNotIsolatedCaller("getProcessMemoryInfo");
5892        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5893        for (int i=pids.length-1; i>=0; i--) {
5894            ProcessRecord proc;
5895            int oomAdj;
5896            synchronized (this) {
5897                synchronized (mPidsSelfLocked) {
5898                    proc = mPidsSelfLocked.get(pids[i]);
5899                    oomAdj = proc != null ? proc.setAdj : 0;
5900                }
5901            }
5902            infos[i] = new Debug.MemoryInfo();
5903            Debug.getMemoryInfo(pids[i], infos[i]);
5904            if (proc != null) {
5905                synchronized (this) {
5906                    if (proc.thread != null && proc.setAdj == oomAdj) {
5907                        // Record this for posterity if the process has been stable.
5908                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5909                                infos[i].getTotalUss(), false, proc.pkgList);
5910                    }
5911                }
5912            }
5913        }
5914        return infos;
5915    }
5916
5917    @Override
5918    public long[] getProcessPss(int[] pids) {
5919        enforceNotIsolatedCaller("getProcessPss");
5920        long[] pss = new long[pids.length];
5921        for (int i=pids.length-1; i>=0; i--) {
5922            ProcessRecord proc;
5923            int oomAdj;
5924            synchronized (this) {
5925                synchronized (mPidsSelfLocked) {
5926                    proc = mPidsSelfLocked.get(pids[i]);
5927                    oomAdj = proc != null ? proc.setAdj : 0;
5928                }
5929            }
5930            long[] tmpUss = new long[1];
5931            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5932            if (proc != null) {
5933                synchronized (this) {
5934                    if (proc.thread != null && proc.setAdj == oomAdj) {
5935                        // Record this for posterity if the process has been stable.
5936                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5937                    }
5938                }
5939            }
5940        }
5941        return pss;
5942    }
5943
5944    @Override
5945    public void killApplicationProcess(String processName, int uid) {
5946        if (processName == null) {
5947            return;
5948        }
5949
5950        int callerUid = Binder.getCallingUid();
5951        // Only the system server can kill an application
5952        if (callerUid == Process.SYSTEM_UID) {
5953            synchronized (this) {
5954                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5955                if (app != null && app.thread != null) {
5956                    try {
5957                        app.thread.scheduleSuicide();
5958                    } catch (RemoteException e) {
5959                        // If the other end already died, then our work here is done.
5960                    }
5961                } else {
5962                    Slog.w(TAG, "Process/uid not found attempting kill of "
5963                            + processName + " / " + uid);
5964                }
5965            }
5966        } else {
5967            throw new SecurityException(callerUid + " cannot kill app process: " +
5968                    processName);
5969        }
5970    }
5971
5972    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5973        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5974                false, true, false, false, UserHandle.getUserId(uid), reason);
5975    }
5976
5977    private void finishForceStopPackageLocked(final String packageName, int uid) {
5978        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5979                Uri.fromParts("package", packageName, null));
5980        if (!mProcessesReady) {
5981            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5982                    | Intent.FLAG_RECEIVER_FOREGROUND);
5983        }
5984        intent.putExtra(Intent.EXTRA_UID, uid);
5985        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5986        broadcastIntentLocked(null, null, intent,
5987                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5988                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5989    }
5990
5991
5992    private final boolean killPackageProcessesLocked(String packageName, int appId,
5993            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5994            boolean doit, boolean evenPersistent, String reason) {
5995        ArrayList<ProcessRecord> procs = new ArrayList<>();
5996
5997        // Remove all processes this package may have touched: all with the
5998        // same UID (except for the system or root user), and all whose name
5999        // matches the package name.
6000        final int NP = mProcessNames.getMap().size();
6001        for (int ip=0; ip<NP; ip++) {
6002            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6003            final int NA = apps.size();
6004            for (int ia=0; ia<NA; ia++) {
6005                ProcessRecord app = apps.valueAt(ia);
6006                if (app.persistent && !evenPersistent) {
6007                    // we don't kill persistent processes
6008                    continue;
6009                }
6010                if (app.removed) {
6011                    if (doit) {
6012                        procs.add(app);
6013                    }
6014                    continue;
6015                }
6016
6017                // Skip process if it doesn't meet our oom adj requirement.
6018                if (app.setAdj < minOomAdj) {
6019                    continue;
6020                }
6021
6022                // If no package is specified, we call all processes under the
6023                // give user id.
6024                if (packageName == null) {
6025                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
6026                        continue;
6027                    }
6028                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
6029                        continue;
6030                    }
6031                // Package has been specified, we want to hit all processes
6032                // that match it.  We need to qualify this by the processes
6033                // that are running under the specified app and user ID.
6034                } else {
6035                    final boolean isDep = app.pkgDeps != null
6036                            && app.pkgDeps.contains(packageName);
6037                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
6038                        continue;
6039                    }
6040                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
6041                        continue;
6042                    }
6043                    if (!app.pkgList.containsKey(packageName) && !isDep) {
6044                        continue;
6045                    }
6046                }
6047
6048                // Process has passed all conditions, kill it!
6049                if (!doit) {
6050                    return true;
6051                }
6052                app.removed = true;
6053                procs.add(app);
6054            }
6055        }
6056
6057        int N = procs.size();
6058        for (int i=0; i<N; i++) {
6059            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
6060        }
6061        updateOomAdjLocked();
6062        return N > 0;
6063    }
6064
6065    private void cleanupDisabledPackageComponentsLocked(
6066            String packageName, int userId, boolean killProcess, String[] changedClasses) {
6067
6068        Set<String> disabledClasses = null;
6069        boolean packageDisabled = false;
6070        IPackageManager pm = AppGlobals.getPackageManager();
6071
6072        if (changedClasses == null) {
6073            // Nothing changed...
6074            return;
6075        }
6076
6077        // Determine enable/disable state of the package and its components.
6078        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6079        for (int i = changedClasses.length - 1; i >= 0; i--) {
6080            final String changedClass = changedClasses[i];
6081
6082            if (changedClass.equals(packageName)) {
6083                try {
6084                    // Entire package setting changed
6085                    enabled = pm.getApplicationEnabledSetting(packageName,
6086                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6087                } catch (Exception e) {
6088                    // No such package/component; probably racing with uninstall.  In any
6089                    // event it means we have nothing further to do here.
6090                    return;
6091                }
6092                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6093                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6094                if (packageDisabled) {
6095                    // Entire package is disabled.
6096                    // No need to continue to check component states.
6097                    disabledClasses = null;
6098                    break;
6099                }
6100            } else {
6101                try {
6102                    enabled = pm.getComponentEnabledSetting(
6103                            new ComponentName(packageName, changedClass),
6104                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6105                } catch (Exception e) {
6106                    // As above, probably racing with uninstall.
6107                    return;
6108                }
6109                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6110                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6111                    if (disabledClasses == null) {
6112                        disabledClasses = new ArraySet<>(changedClasses.length);
6113                    }
6114                    disabledClasses.add(changedClass);
6115                }
6116            }
6117        }
6118
6119        if (!packageDisabled && disabledClasses == null) {
6120            // Nothing to do here...
6121            return;
6122        }
6123
6124        // Clean-up disabled activities.
6125        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6126                packageName, disabledClasses, true, false, userId) && mBooted) {
6127            mStackSupervisor.resumeFocusedStackTopActivityLocked();
6128            mStackSupervisor.scheduleIdleLocked();
6129        }
6130
6131        // Clean-up disabled tasks
6132        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6133
6134        // Clean-up disabled services.
6135        mServices.bringDownDisabledPackageServicesLocked(
6136                packageName, disabledClasses, userId, false, killProcess, true);
6137
6138        // Clean-up disabled providers.
6139        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6140        mProviderMap.collectPackageProvidersLocked(
6141                packageName, disabledClasses, true, false, userId, providers);
6142        for (int i = providers.size() - 1; i >= 0; i--) {
6143            removeDyingProviderLocked(null, providers.get(i), true);
6144        }
6145
6146        // Clean-up disabled broadcast receivers.
6147        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6148            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6149                    packageName, disabledClasses, userId, true);
6150        }
6151
6152    }
6153
6154    final boolean clearBroadcastQueueForUserLocked(int userId) {
6155        boolean didSomething = false;
6156        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6157            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6158                    null, null, userId, true);
6159        }
6160        return didSomething;
6161    }
6162
6163    final boolean forceStopPackageLocked(String packageName, int appId,
6164            boolean callerWillRestart, boolean purgeCache, boolean doit,
6165            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6166        int i;
6167
6168        if (userId == UserHandle.USER_ALL && packageName == null) {
6169            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6170        }
6171
6172        if (appId < 0 && packageName != null) {
6173            try {
6174                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6175                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6176            } catch (RemoteException e) {
6177            }
6178        }
6179
6180        if (doit) {
6181            if (packageName != null) {
6182                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6183                        + " user=" + userId + ": " + reason);
6184            } else {
6185                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6186            }
6187
6188            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6189        }
6190
6191        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6192                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6193                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6194
6195        didSomething |= mActivityStarter.clearPendingActivityLaunchesLocked(packageName);
6196
6197        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6198                packageName, null, doit, evenPersistent, userId)) {
6199            if (!doit) {
6200                return true;
6201            }
6202            didSomething = true;
6203        }
6204
6205        if (mServices.bringDownDisabledPackageServicesLocked(
6206                packageName, null, userId, evenPersistent, true, doit)) {
6207            if (!doit) {
6208                return true;
6209            }
6210            didSomething = true;
6211        }
6212
6213        if (packageName == null) {
6214            // Remove all sticky broadcasts from this user.
6215            mStickyBroadcasts.remove(userId);
6216        }
6217
6218        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6219        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6220                userId, providers)) {
6221            if (!doit) {
6222                return true;
6223            }
6224            didSomething = true;
6225        }
6226        for (i = providers.size() - 1; i >= 0; i--) {
6227            removeDyingProviderLocked(null, providers.get(i), true);
6228        }
6229
6230        // Remove transient permissions granted from/to this package/user
6231        removeUriPermissionsForPackageLocked(packageName, userId, false);
6232
6233        if (doit) {
6234            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6235                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6236                        packageName, null, userId, doit);
6237            }
6238        }
6239
6240        if (packageName == null || uninstalling) {
6241            // Remove pending intents.  For now we only do this when force
6242            // stopping users, because we have some problems when doing this
6243            // for packages -- app widgets are not currently cleaned up for
6244            // such packages, so they can be left with bad pending intents.
6245            if (mIntentSenderRecords.size() > 0) {
6246                Iterator<WeakReference<PendingIntentRecord>> it
6247                        = mIntentSenderRecords.values().iterator();
6248                while (it.hasNext()) {
6249                    WeakReference<PendingIntentRecord> wpir = it.next();
6250                    if (wpir == null) {
6251                        it.remove();
6252                        continue;
6253                    }
6254                    PendingIntentRecord pir = wpir.get();
6255                    if (pir == null) {
6256                        it.remove();
6257                        continue;
6258                    }
6259                    if (packageName == null) {
6260                        // Stopping user, remove all objects for the user.
6261                        if (pir.key.userId != userId) {
6262                            // Not the same user, skip it.
6263                            continue;
6264                        }
6265                    } else {
6266                        if (UserHandle.getAppId(pir.uid) != appId) {
6267                            // Different app id, skip it.
6268                            continue;
6269                        }
6270                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6271                            // Different user, skip it.
6272                            continue;
6273                        }
6274                        if (!pir.key.packageName.equals(packageName)) {
6275                            // Different package, skip it.
6276                            continue;
6277                        }
6278                    }
6279                    if (!doit) {
6280                        return true;
6281                    }
6282                    didSomething = true;
6283                    it.remove();
6284                    pir.canceled = true;
6285                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6286                        pir.key.activity.pendingResults.remove(pir.ref);
6287                    }
6288                }
6289            }
6290        }
6291
6292        if (doit) {
6293            if (purgeCache && packageName != null) {
6294                AttributeCache ac = AttributeCache.instance();
6295                if (ac != null) {
6296                    ac.removePackage(packageName);
6297                }
6298            }
6299            if (mBooted) {
6300                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6301                mStackSupervisor.scheduleIdleLocked();
6302            }
6303        }
6304
6305        return didSomething;
6306    }
6307
6308    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6309        ProcessRecord old = mProcessNames.remove(name, uid);
6310        if (old != null) {
6311            old.uidRecord.numProcs--;
6312            if (old.uidRecord.numProcs == 0) {
6313                // No more processes using this uid, tell clients it is gone.
6314                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6315                        "No more processes in " + old.uidRecord);
6316                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6317                mActiveUids.remove(uid);
6318                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6319            }
6320            old.uidRecord = null;
6321        }
6322        mIsolatedProcesses.remove(uid);
6323        return old;
6324    }
6325
6326    private final void addProcessNameLocked(ProcessRecord proc) {
6327        // We shouldn't already have a process under this name, but just in case we
6328        // need to clean up whatever may be there now.
6329        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6330        if (old == proc && proc.persistent) {
6331            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6332            Slog.w(TAG, "Re-adding persistent process " + proc);
6333        } else if (old != null) {
6334            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6335        }
6336        UidRecord uidRec = mActiveUids.get(proc.uid);
6337        if (uidRec == null) {
6338            uidRec = new UidRecord(proc.uid);
6339            // This is the first appearance of the uid, report it now!
6340            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6341                    "Creating new process uid: " + uidRec);
6342            mActiveUids.put(proc.uid, uidRec);
6343            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6344            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6345        }
6346        proc.uidRecord = uidRec;
6347
6348        // Reset render thread tid if it was already set, so new process can set it again.
6349        proc.renderThreadTid = 0;
6350        uidRec.numProcs++;
6351        mProcessNames.put(proc.processName, proc.uid, proc);
6352        if (proc.isolated) {
6353            mIsolatedProcesses.put(proc.uid, proc);
6354        }
6355    }
6356
6357    boolean removeProcessLocked(ProcessRecord app,
6358            boolean callerWillRestart, boolean allowRestart, String reason) {
6359        final String name = app.processName;
6360        final int uid = app.uid;
6361        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6362            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6363
6364        ProcessRecord old = mProcessNames.get(name, uid);
6365        if (old != app) {
6366            // This process is no longer active, so nothing to do.
6367            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6368            return false;
6369        }
6370        removeProcessNameLocked(name, uid);
6371        if (mHeavyWeightProcess == app) {
6372            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6373                    mHeavyWeightProcess.userId, 0));
6374            mHeavyWeightProcess = null;
6375        }
6376        boolean needRestart = false;
6377        if (app.pid > 0 && app.pid != MY_PID) {
6378            int pid = app.pid;
6379            synchronized (mPidsSelfLocked) {
6380                mPidsSelfLocked.remove(pid);
6381                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6382            }
6383            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6384            if (app.isolated) {
6385                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6386            }
6387            boolean willRestart = false;
6388            if (app.persistent && !app.isolated) {
6389                if (!callerWillRestart) {
6390                    willRestart = true;
6391                } else {
6392                    needRestart = true;
6393                }
6394            }
6395            app.kill(reason, true);
6396            handleAppDiedLocked(app, willRestart, allowRestart);
6397            if (willRestart) {
6398                removeLruProcessLocked(app);
6399                addAppLocked(app.info, false, null /* ABI override */);
6400            }
6401        } else {
6402            mRemovedProcesses.add(app);
6403        }
6404
6405        return needRestart;
6406    }
6407
6408    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6409        cleanupAppInLaunchingProvidersLocked(app, true);
6410        removeProcessLocked(app, false, true, "timeout publishing content providers");
6411    }
6412
6413    private final void processStartTimedOutLocked(ProcessRecord app) {
6414        final int pid = app.pid;
6415        boolean gone = false;
6416        synchronized (mPidsSelfLocked) {
6417            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6418            if (knownApp != null && knownApp.thread == null) {
6419                mPidsSelfLocked.remove(pid);
6420                gone = true;
6421            }
6422        }
6423
6424        if (gone) {
6425            Slog.w(TAG, "Process " + app + " failed to attach");
6426            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6427                    pid, app.uid, app.processName);
6428            removeProcessNameLocked(app.processName, app.uid);
6429            if (mHeavyWeightProcess == app) {
6430                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6431                        mHeavyWeightProcess.userId, 0));
6432                mHeavyWeightProcess = null;
6433            }
6434            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6435            if (app.isolated) {
6436                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6437            }
6438            // Take care of any launching providers waiting for this process.
6439            cleanupAppInLaunchingProvidersLocked(app, true);
6440            // Take care of any services that are waiting for the process.
6441            mServices.processStartTimedOutLocked(app);
6442            app.kill("start timeout", true);
6443            removeLruProcessLocked(app);
6444            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6445                Slog.w(TAG, "Unattached app died before backup, skipping");
6446                mHandler.post(new Runnable() {
6447                @Override
6448                    public void run(){
6449                        try {
6450                            IBackupManager bm = IBackupManager.Stub.asInterface(
6451                                    ServiceManager.getService(Context.BACKUP_SERVICE));
6452                            bm.agentDisconnected(app.info.packageName);
6453                        } catch (RemoteException e) {
6454                            // Can't happen; the backup manager is local
6455                        }
6456                    }
6457                });
6458            }
6459            if (isPendingBroadcastProcessLocked(pid)) {
6460                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6461                skipPendingBroadcastLocked(pid);
6462            }
6463        } else {
6464            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6465        }
6466    }
6467
6468    private final boolean attachApplicationLocked(IApplicationThread thread,
6469            int pid) {
6470
6471        // Find the application record that is being attached...  either via
6472        // the pid if we are running in multiple processes, or just pull the
6473        // next app record if we are emulating process with anonymous threads.
6474        ProcessRecord app;
6475        if (pid != MY_PID && pid >= 0) {
6476            synchronized (mPidsSelfLocked) {
6477                app = mPidsSelfLocked.get(pid);
6478            }
6479        } else {
6480            app = null;
6481        }
6482
6483        if (app == null) {
6484            Slog.w(TAG, "No pending application record for pid " + pid
6485                    + " (IApplicationThread " + thread + "); dropping process");
6486            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6487            if (pid > 0 && pid != MY_PID) {
6488                Process.killProcessQuiet(pid);
6489                //TODO: killProcessGroup(app.info.uid, pid);
6490            } else {
6491                try {
6492                    thread.scheduleExit();
6493                } catch (Exception e) {
6494                    // Ignore exceptions.
6495                }
6496            }
6497            return false;
6498        }
6499
6500        // If this application record is still attached to a previous
6501        // process, clean it up now.
6502        if (app.thread != null) {
6503            handleAppDiedLocked(app, true, true);
6504        }
6505
6506        // Tell the process all about itself.
6507
6508        if (DEBUG_ALL) Slog.v(
6509                TAG, "Binding process pid " + pid + " to record " + app);
6510
6511        final String processName = app.processName;
6512        try {
6513            AppDeathRecipient adr = new AppDeathRecipient(
6514                    app, pid, thread);
6515            thread.asBinder().linkToDeath(adr, 0);
6516            app.deathRecipient = adr;
6517        } catch (RemoteException e) {
6518            app.resetPackageList(mProcessStats);
6519            startProcessLocked(app, "link fail", processName);
6520            return false;
6521        }
6522
6523        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6524
6525        app.makeActive(thread, mProcessStats);
6526        app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6527        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6528        app.forcingToForeground = null;
6529        updateProcessForegroundLocked(app, false, false);
6530        app.hasShownUi = false;
6531        app.debugging = false;
6532        app.cached = false;
6533        app.killedByAm = false;
6534        app.killed = false;
6535
6536
6537        // We carefully use the same state that PackageManager uses for
6538        // filtering, since we use this flag to decide if we need to install
6539        // providers when user is unlocked later
6540        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6541
6542        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6543
6544        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6545        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6546
6547        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6548            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6549            msg.obj = app;
6550            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6551        }
6552
6553        if (!normalMode) {
6554            Slog.i(TAG, "Launching preboot mode app: " + app);
6555        }
6556
6557        if (DEBUG_ALL) Slog.v(
6558            TAG, "New app record " + app
6559            + " thread=" + thread.asBinder() + " pid=" + pid);
6560        try {
6561            int testMode = IApplicationThread.DEBUG_OFF;
6562            if (mDebugApp != null && mDebugApp.equals(processName)) {
6563                testMode = mWaitForDebugger
6564                    ? IApplicationThread.DEBUG_WAIT
6565                    : IApplicationThread.DEBUG_ON;
6566                app.debugging = true;
6567                if (mDebugTransient) {
6568                    mDebugApp = mOrigDebugApp;
6569                    mWaitForDebugger = mOrigWaitForDebugger;
6570                }
6571            }
6572            String profileFile = app.instrumentationProfileFile;
6573            ParcelFileDescriptor profileFd = null;
6574            int samplingInterval = 0;
6575            boolean profileAutoStop = false;
6576            boolean profileStreamingOutput = false;
6577            if (mProfileApp != null && mProfileApp.equals(processName)) {
6578                mProfileProc = app;
6579                profileFile = mProfileFile;
6580                profileFd = mProfileFd;
6581                samplingInterval = mSamplingInterval;
6582                profileAutoStop = mAutoStopProfiler;
6583                profileStreamingOutput = mStreamingOutput;
6584            }
6585            boolean enableTrackAllocation = false;
6586            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6587                enableTrackAllocation = true;
6588                mTrackAllocationApp = null;
6589            }
6590
6591            // If the app is being launched for restore or full backup, set it up specially
6592            boolean isRestrictedBackupMode = false;
6593            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6594                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6595                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6596                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6597                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6598            }
6599
6600            if (app.instrumentationClass != null) {
6601                notifyPackageUse(app.instrumentationClass.getPackageName(),
6602                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6603            }
6604            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6605                    + processName + " with config " + mConfiguration);
6606            ApplicationInfo appInfo = app.instrumentationInfo != null
6607                    ? app.instrumentationInfo : app.info;
6608            app.compat = compatibilityInfoForPackageLocked(appInfo);
6609            if (profileFd != null) {
6610                profileFd = profileFd.dup();
6611            }
6612            ProfilerInfo profilerInfo = profileFile == null ? null
6613                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop,
6614                                       profileStreamingOutput);
6615            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6616                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6617                    app.instrumentationUiAutomationConnection, testMode,
6618                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6619                    isRestrictedBackupMode || !normalMode, app.persistent,
6620                    new Configuration(mConfiguration), app.compat,
6621                    getCommonServicesLocked(app.isolated),
6622                    mCoreSettingsObserver.getCoreSettingsLocked());
6623            updateLruProcessLocked(app, false, null);
6624            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6625        } catch (Exception e) {
6626            // todo: Yikes!  What should we do?  For now we will try to
6627            // start another process, but that could easily get us in
6628            // an infinite loop of restarting processes...
6629            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6630
6631            app.resetPackageList(mProcessStats);
6632            app.unlinkDeathRecipient();
6633            startProcessLocked(app, "bind fail", processName);
6634            return false;
6635        }
6636
6637        // Remove this record from the list of starting applications.
6638        mPersistentStartingProcesses.remove(app);
6639        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6640                "Attach application locked removing on hold: " + app);
6641        mProcessesOnHold.remove(app);
6642
6643        boolean badApp = false;
6644        boolean didSomething = false;
6645
6646        // See if the top visible activity is waiting to run in this process...
6647        if (normalMode) {
6648            try {
6649                if (mStackSupervisor.attachApplicationLocked(app)) {
6650                    didSomething = true;
6651                }
6652            } catch (Exception e) {
6653                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6654                badApp = true;
6655            }
6656        }
6657
6658        // Find any services that should be running in this process...
6659        if (!badApp) {
6660            try {
6661                didSomething |= mServices.attachApplicationLocked(app, processName);
6662            } catch (Exception e) {
6663                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6664                badApp = true;
6665            }
6666        }
6667
6668        // Check if a next-broadcast receiver is in this process...
6669        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6670            try {
6671                didSomething |= sendPendingBroadcastsLocked(app);
6672            } catch (Exception e) {
6673                // If the app died trying to launch the receiver we declare it 'bad'
6674                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6675                badApp = true;
6676            }
6677        }
6678
6679        // Check whether the next backup agent is in this process...
6680        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6681            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6682                    "New app is backup target, launching agent for " + app);
6683            notifyPackageUse(mBackupTarget.appInfo.packageName,
6684                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6685            try {
6686                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6687                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6688                        mBackupTarget.backupMode);
6689            } catch (Exception e) {
6690                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6691                badApp = true;
6692            }
6693        }
6694
6695        if (badApp) {
6696            app.kill("error during init", true);
6697            handleAppDiedLocked(app, false, true);
6698            return false;
6699        }
6700
6701        if (!didSomething) {
6702            updateOomAdjLocked();
6703        }
6704
6705        return true;
6706    }
6707
6708    @Override
6709    public final void attachApplication(IApplicationThread thread) {
6710        synchronized (this) {
6711            int callingPid = Binder.getCallingPid();
6712            final long origId = Binder.clearCallingIdentity();
6713            attachApplicationLocked(thread, callingPid);
6714            Binder.restoreCallingIdentity(origId);
6715        }
6716    }
6717
6718    @Override
6719    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6720        final long origId = Binder.clearCallingIdentity();
6721        synchronized (this) {
6722            ActivityStack stack = ActivityRecord.getStackLocked(token);
6723            if (stack != null) {
6724                ActivityRecord r =
6725                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6726                if (stopProfiling) {
6727                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6728                        try {
6729                            mProfileFd.close();
6730                        } catch (IOException e) {
6731                        }
6732                        clearProfilerLocked();
6733                    }
6734                }
6735            }
6736        }
6737        Binder.restoreCallingIdentity(origId);
6738    }
6739
6740    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6741        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6742                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6743    }
6744
6745    void enableScreenAfterBoot() {
6746        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6747                SystemClock.uptimeMillis());
6748        mWindowManager.enableScreenAfterBoot();
6749
6750        synchronized (this) {
6751            updateEventDispatchingLocked();
6752        }
6753    }
6754
6755    @Override
6756    public void showBootMessage(final CharSequence msg, final boolean always) {
6757        if (Binder.getCallingUid() != Process.myUid()) {
6758            throw new SecurityException();
6759        }
6760        mWindowManager.showBootMessage(msg, always);
6761    }
6762
6763    @Override
6764    public void keyguardWaitingForActivityDrawn() {
6765        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6766        final long token = Binder.clearCallingIdentity();
6767        try {
6768            synchronized (this) {
6769                if (DEBUG_LOCKSCREEN) logLockScreen("");
6770                mWindowManager.keyguardWaitingForActivityDrawn();
6771                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6772                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6773                    updateSleepIfNeededLocked();
6774                }
6775            }
6776        } finally {
6777            Binder.restoreCallingIdentity(token);
6778        }
6779    }
6780
6781    @Override
6782    public void keyguardGoingAway(int flags) {
6783        enforceNotIsolatedCaller("keyguardGoingAway");
6784        final long token = Binder.clearCallingIdentity();
6785        try {
6786            synchronized (this) {
6787                if (DEBUG_LOCKSCREEN) logLockScreen("");
6788                mWindowManager.keyguardGoingAway(flags);
6789                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6790                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6791                    updateSleepIfNeededLocked();
6792
6793                    // Some stack visibility might change (e.g. docked stack)
6794                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6795                    applyVrModeIfNeededLocked(mFocusedActivity, true);
6796                }
6797            }
6798        } finally {
6799            Binder.restoreCallingIdentity(token);
6800        }
6801    }
6802
6803    final void finishBooting() {
6804        synchronized (this) {
6805            if (!mBootAnimationComplete) {
6806                mCallFinishBooting = true;
6807                return;
6808            }
6809            mCallFinishBooting = false;
6810        }
6811
6812        ArraySet<String> completedIsas = new ArraySet<String>();
6813        for (String abi : Build.SUPPORTED_ABIS) {
6814            Process.zygoteProcess.establishZygoteConnectionForAbi(abi);
6815            final String instructionSet = VMRuntime.getInstructionSet(abi);
6816            if (!completedIsas.contains(instructionSet)) {
6817                try {
6818                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6819                } catch (InstallerException e) {
6820                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6821                            e.getMessage() +")");
6822                }
6823                completedIsas.add(instructionSet);
6824            }
6825        }
6826
6827        IntentFilter pkgFilter = new IntentFilter();
6828        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6829        pkgFilter.addDataScheme("package");
6830        mContext.registerReceiver(new BroadcastReceiver() {
6831            @Override
6832            public void onReceive(Context context, Intent intent) {
6833                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6834                if (pkgs != null) {
6835                    for (String pkg : pkgs) {
6836                        synchronized (ActivityManagerService.this) {
6837                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6838                                    0, "query restart")) {
6839                                setResultCode(Activity.RESULT_OK);
6840                                return;
6841                            }
6842                        }
6843                    }
6844                }
6845            }
6846        }, pkgFilter);
6847
6848        IntentFilter dumpheapFilter = new IntentFilter();
6849        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6850        mContext.registerReceiver(new BroadcastReceiver() {
6851            @Override
6852            public void onReceive(Context context, Intent intent) {
6853                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6854                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6855                } else {
6856                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6857                }
6858            }
6859        }, dumpheapFilter);
6860
6861        // Let system services know.
6862        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6863
6864        synchronized (this) {
6865            // Ensure that any processes we had put on hold are now started
6866            // up.
6867            final int NP = mProcessesOnHold.size();
6868            if (NP > 0) {
6869                ArrayList<ProcessRecord> procs =
6870                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6871                for (int ip=0; ip<NP; ip++) {
6872                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6873                            + procs.get(ip));
6874                    startProcessLocked(procs.get(ip), "on-hold", null);
6875                }
6876            }
6877
6878            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6879                // Start looking for apps that are abusing wake locks.
6880                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6881                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6882                // Tell anyone interested that we are done booting!
6883                SystemProperties.set("sys.boot_completed", "1");
6884
6885                // And trigger dev.bootcomplete if we are not showing encryption progress
6886                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6887                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6888                    SystemProperties.set("dev.bootcomplete", "1");
6889                }
6890                mUserController.sendBootCompletedLocked(
6891                        new IIntentReceiver.Stub() {
6892                            @Override
6893                            public void performReceive(Intent intent, int resultCode,
6894                                    String data, Bundle extras, boolean ordered,
6895                                    boolean sticky, int sendingUser) {
6896                                synchronized (ActivityManagerService.this) {
6897                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6898                                            true, false);
6899                                }
6900                            }
6901                        });
6902                scheduleStartProfilesLocked();
6903            }
6904        }
6905    }
6906
6907    @Override
6908    public void bootAnimationComplete() {
6909        final boolean callFinishBooting;
6910        synchronized (this) {
6911            callFinishBooting = mCallFinishBooting;
6912            mBootAnimationComplete = true;
6913        }
6914        if (callFinishBooting) {
6915            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6916            finishBooting();
6917            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6918        }
6919    }
6920
6921    final void ensureBootCompleted() {
6922        boolean booting;
6923        boolean enableScreen;
6924        synchronized (this) {
6925            booting = mBooting;
6926            mBooting = false;
6927            enableScreen = !mBooted;
6928            mBooted = true;
6929        }
6930
6931        if (booting) {
6932            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6933            finishBooting();
6934            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6935        }
6936
6937        if (enableScreen) {
6938            enableScreenAfterBoot();
6939        }
6940    }
6941
6942    @Override
6943    public final void activityResumed(IBinder token) {
6944        final long origId = Binder.clearCallingIdentity();
6945        synchronized(this) {
6946            ActivityStack stack = ActivityRecord.getStackLocked(token);
6947            if (stack != null) {
6948                stack.activityResumedLocked(token);
6949            }
6950        }
6951        Binder.restoreCallingIdentity(origId);
6952    }
6953
6954    @Override
6955    public final void activityPaused(IBinder token) {
6956        final long origId = Binder.clearCallingIdentity();
6957        synchronized(this) {
6958            ActivityStack stack = ActivityRecord.getStackLocked(token);
6959            if (stack != null) {
6960                stack.activityPausedLocked(token, false);
6961            }
6962        }
6963        Binder.restoreCallingIdentity(origId);
6964    }
6965
6966    @Override
6967    public final void activityStopped(IBinder token, Bundle icicle,
6968            PersistableBundle persistentState, CharSequence description) {
6969        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6970
6971        // Refuse possible leaked file descriptors
6972        if (icicle != null && icicle.hasFileDescriptors()) {
6973            throw new IllegalArgumentException("File descriptors passed in Bundle");
6974        }
6975
6976        final long origId = Binder.clearCallingIdentity();
6977
6978        synchronized (this) {
6979            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6980            if (r != null) {
6981                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6982            }
6983        }
6984
6985        trimApplications();
6986
6987        Binder.restoreCallingIdentity(origId);
6988    }
6989
6990    @Override
6991    public final void activityDestroyed(IBinder token) {
6992        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6993        synchronized (this) {
6994            ActivityStack stack = ActivityRecord.getStackLocked(token);
6995            if (stack != null) {
6996                stack.activityDestroyedLocked(token, "activityDestroyed");
6997            }
6998        }
6999    }
7000
7001    @Override
7002    public final void activityRelaunched(IBinder token) {
7003        final long origId = Binder.clearCallingIdentity();
7004        synchronized (this) {
7005            mStackSupervisor.activityRelaunchedLocked(token);
7006        }
7007        Binder.restoreCallingIdentity(origId);
7008    }
7009
7010    @Override
7011    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
7012            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
7013        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
7014                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
7015        synchronized (this) {
7016            ActivityRecord record = ActivityRecord.isInStackLocked(token);
7017            if (record == null) {
7018                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
7019                        + "found for: " + token);
7020            }
7021            record.setSizeConfigurations(horizontalSizeConfiguration,
7022                    verticalSizeConfigurations, smallestSizeConfigurations);
7023        }
7024    }
7025
7026    @Override
7027    public final void backgroundResourcesReleased(IBinder token) {
7028        final long origId = Binder.clearCallingIdentity();
7029        try {
7030            synchronized (this) {
7031                ActivityStack stack = ActivityRecord.getStackLocked(token);
7032                if (stack != null) {
7033                    stack.backgroundResourcesReleased();
7034                }
7035            }
7036        } finally {
7037            Binder.restoreCallingIdentity(origId);
7038        }
7039    }
7040
7041    @Override
7042    public final void notifyLaunchTaskBehindComplete(IBinder token) {
7043        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
7044    }
7045
7046    @Override
7047    public final void notifyEnterAnimationComplete(IBinder token) {
7048        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
7049    }
7050
7051    @Override
7052    public String getCallingPackage(IBinder token) {
7053        synchronized (this) {
7054            ActivityRecord r = getCallingRecordLocked(token);
7055            return r != null ? r.info.packageName : null;
7056        }
7057    }
7058
7059    @Override
7060    public ComponentName getCallingActivity(IBinder token) {
7061        synchronized (this) {
7062            ActivityRecord r = getCallingRecordLocked(token);
7063            return r != null ? r.intent.getComponent() : null;
7064        }
7065    }
7066
7067    private ActivityRecord getCallingRecordLocked(IBinder token) {
7068        ActivityRecord r = ActivityRecord.isInStackLocked(token);
7069        if (r == null) {
7070            return null;
7071        }
7072        return r.resultTo;
7073    }
7074
7075    @Override
7076    public ComponentName getActivityClassForToken(IBinder token) {
7077        synchronized(this) {
7078            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7079            if (r == null) {
7080                return null;
7081            }
7082            return r.intent.getComponent();
7083        }
7084    }
7085
7086    @Override
7087    public String getPackageForToken(IBinder token) {
7088        synchronized(this) {
7089            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7090            if (r == null) {
7091                return null;
7092            }
7093            return r.packageName;
7094        }
7095    }
7096
7097    @Override
7098    public boolean isRootVoiceInteraction(IBinder token) {
7099        synchronized(this) {
7100            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7101            if (r == null) {
7102                return false;
7103            }
7104            return r.rootVoiceInteraction;
7105        }
7106    }
7107
7108    @Override
7109    public IIntentSender getIntentSender(int type,
7110            String packageName, IBinder token, String resultWho,
7111            int requestCode, Intent[] intents, String[] resolvedTypes,
7112            int flags, Bundle bOptions, int userId) {
7113        enforceNotIsolatedCaller("getIntentSender");
7114        // Refuse possible leaked file descriptors
7115        if (intents != null) {
7116            if (intents.length < 1) {
7117                throw new IllegalArgumentException("Intents array length must be >= 1");
7118            }
7119            for (int i=0; i<intents.length; i++) {
7120                Intent intent = intents[i];
7121                if (intent != null) {
7122                    if (intent.hasFileDescriptors()) {
7123                        throw new IllegalArgumentException("File descriptors passed in Intent");
7124                    }
7125                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7126                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7127                        throw new IllegalArgumentException(
7128                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7129                    }
7130                    intents[i] = new Intent(intent);
7131                }
7132            }
7133            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7134                throw new IllegalArgumentException(
7135                        "Intent array length does not match resolvedTypes length");
7136            }
7137        }
7138        if (bOptions != null) {
7139            if (bOptions.hasFileDescriptors()) {
7140                throw new IllegalArgumentException("File descriptors passed in options");
7141            }
7142        }
7143
7144        synchronized(this) {
7145            int callingUid = Binder.getCallingUid();
7146            int origUserId = userId;
7147            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7148                    type == ActivityManager.INTENT_SENDER_BROADCAST,
7149                    ALLOW_NON_FULL, "getIntentSender", null);
7150            if (origUserId == UserHandle.USER_CURRENT) {
7151                // We don't want to evaluate this until the pending intent is
7152                // actually executed.  However, we do want to always do the
7153                // security checking for it above.
7154                userId = UserHandle.USER_CURRENT;
7155            }
7156            try {
7157                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
7158                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7159                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7160                    if (!UserHandle.isSameApp(callingUid, uid)) {
7161                        String msg = "Permission Denial: getIntentSender() from pid="
7162                            + Binder.getCallingPid()
7163                            + ", uid=" + Binder.getCallingUid()
7164                            + ", (need uid=" + uid + ")"
7165                            + " is not allowed to send as package " + packageName;
7166                        Slog.w(TAG, msg);
7167                        throw new SecurityException(msg);
7168                    }
7169                }
7170
7171                return getIntentSenderLocked(type, packageName, callingUid, userId,
7172                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7173
7174            } catch (RemoteException e) {
7175                throw new SecurityException(e);
7176            }
7177        }
7178    }
7179
7180    IIntentSender getIntentSenderLocked(int type, String packageName,
7181            int callingUid, int userId, IBinder token, String resultWho,
7182            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7183            Bundle bOptions) {
7184        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7185        ActivityRecord activity = null;
7186        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7187            activity = ActivityRecord.isInStackLocked(token);
7188            if (activity == null) {
7189                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7190                return null;
7191            }
7192            if (activity.finishing) {
7193                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7194                return null;
7195            }
7196        }
7197
7198        // We're going to be splicing together extras before sending, so we're
7199        // okay poking into any contained extras.
7200        if (intents != null) {
7201            for (int i = 0; i < intents.length; i++) {
7202                intents[i].setDefusable(true);
7203            }
7204        }
7205        Bundle.setDefusable(bOptions, true);
7206
7207        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7208        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7209        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7210        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7211                |PendingIntent.FLAG_UPDATE_CURRENT);
7212
7213        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7214                type, packageName, activity, resultWho,
7215                requestCode, intents, resolvedTypes, flags, bOptions, userId);
7216        WeakReference<PendingIntentRecord> ref;
7217        ref = mIntentSenderRecords.get(key);
7218        PendingIntentRecord rec = ref != null ? ref.get() : null;
7219        if (rec != null) {
7220            if (!cancelCurrent) {
7221                if (updateCurrent) {
7222                    if (rec.key.requestIntent != null) {
7223                        rec.key.requestIntent.replaceExtras(intents != null ?
7224                                intents[intents.length - 1] : null);
7225                    }
7226                    if (intents != null) {
7227                        intents[intents.length-1] = rec.key.requestIntent;
7228                        rec.key.allIntents = intents;
7229                        rec.key.allResolvedTypes = resolvedTypes;
7230                    } else {
7231                        rec.key.allIntents = null;
7232                        rec.key.allResolvedTypes = null;
7233                    }
7234                }
7235                return rec;
7236            }
7237            rec.canceled = true;
7238            mIntentSenderRecords.remove(key);
7239        }
7240        if (noCreate) {
7241            return rec;
7242        }
7243        rec = new PendingIntentRecord(this, key, callingUid);
7244        mIntentSenderRecords.put(key, rec.ref);
7245        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7246            if (activity.pendingResults == null) {
7247                activity.pendingResults
7248                        = new HashSet<WeakReference<PendingIntentRecord>>();
7249            }
7250            activity.pendingResults.add(rec.ref);
7251        }
7252        return rec;
7253    }
7254
7255    @Override
7256    public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7257            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7258        if (target instanceof PendingIntentRecord) {
7259            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7260                    finishedReceiver, requiredPermission, options);
7261        } else {
7262            if (intent == null) {
7263                // Weird case: someone has given us their own custom IIntentSender, and now
7264                // they have someone else trying to send to it but of course this isn't
7265                // really a PendingIntent, so there is no base Intent, and the caller isn't
7266                // supplying an Intent... but we never want to dispatch a null Intent to
7267                // a receiver, so um...  let's make something up.
7268                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7269                intent = new Intent(Intent.ACTION_MAIN);
7270            }
7271            try {
7272                target.send(code, intent, resolvedType, null, requiredPermission, options);
7273            } catch (RemoteException e) {
7274            }
7275            // Platform code can rely on getting a result back when the send is done, but if
7276            // this intent sender is from outside of the system we can't rely on it doing that.
7277            // So instead we don't give it the result receiver, and instead just directly
7278            // report the finish immediately.
7279            if (finishedReceiver != null) {
7280                try {
7281                    finishedReceiver.performReceive(intent, 0,
7282                            null, null, false, false, UserHandle.getCallingUserId());
7283                } catch (RemoteException e) {
7284                }
7285            }
7286            return 0;
7287        }
7288    }
7289
7290    /**
7291     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
7292     *
7293     * <p>{@code callerUid} must be allowed to request such whitelist by calling
7294     * {@link #addTempPowerSaveWhitelistGrantorUid(int)}.
7295     */
7296    void tempWhitelistAppForPowerSave(int callerPid, int callerUid, int targetUid, long duration) {
7297        if (DEBUG_WHITELISTS) {
7298            Slog.d(TAG, "tempWhitelistAppForPowerSave(" + callerPid + ", " + callerUid + ", "
7299                    + targetUid + ", " + duration + ")");
7300        }
7301        synchronized (mPidsSelfLocked) {
7302            final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
7303            if (pr == null) {
7304                Slog.w(TAG, "tempWhitelistAppForPowerSave() no ProcessRecord for pid " + callerPid);
7305                return;
7306            }
7307            if (!pr.whitelistManager) {
7308                if (DEBUG_WHITELISTS) {
7309                    Slog.d(TAG, "tempWhitelistAppForPowerSave() for target " + targetUid + ": pid "
7310                            + callerPid + " is not allowed");
7311                }
7312                return;
7313            }
7314        }
7315
7316        final long token = Binder.clearCallingIdentity();
7317        try {
7318            mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(targetUid, duration,
7319                    true, "pe from uid:" + callerUid);
7320        } finally {
7321            Binder.restoreCallingIdentity(token);
7322        }
7323    }
7324
7325    @Override
7326    public void cancelIntentSender(IIntentSender sender) {
7327        if (!(sender instanceof PendingIntentRecord)) {
7328            return;
7329        }
7330        synchronized(this) {
7331            PendingIntentRecord rec = (PendingIntentRecord)sender;
7332            try {
7333                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7334                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7335                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7336                    String msg = "Permission Denial: cancelIntentSender() from pid="
7337                        + Binder.getCallingPid()
7338                        + ", uid=" + Binder.getCallingUid()
7339                        + " is not allowed to cancel packges "
7340                        + rec.key.packageName;
7341                    Slog.w(TAG, msg);
7342                    throw new SecurityException(msg);
7343                }
7344            } catch (RemoteException e) {
7345                throw new SecurityException(e);
7346            }
7347            cancelIntentSenderLocked(rec, true);
7348        }
7349    }
7350
7351    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7352        rec.canceled = true;
7353        mIntentSenderRecords.remove(rec.key);
7354        if (cleanActivity && rec.key.activity != null) {
7355            rec.key.activity.pendingResults.remove(rec.ref);
7356        }
7357    }
7358
7359    @Override
7360    public String getPackageForIntentSender(IIntentSender pendingResult) {
7361        if (!(pendingResult instanceof PendingIntentRecord)) {
7362            return null;
7363        }
7364        try {
7365            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7366            return res.key.packageName;
7367        } catch (ClassCastException e) {
7368        }
7369        return null;
7370    }
7371
7372    @Override
7373    public int getUidForIntentSender(IIntentSender sender) {
7374        if (sender instanceof PendingIntentRecord) {
7375            try {
7376                PendingIntentRecord res = (PendingIntentRecord)sender;
7377                return res.uid;
7378            } catch (ClassCastException e) {
7379            }
7380        }
7381        return -1;
7382    }
7383
7384    @Override
7385    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7386        if (!(pendingResult instanceof PendingIntentRecord)) {
7387            return false;
7388        }
7389        try {
7390            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7391            if (res.key.allIntents == null) {
7392                return false;
7393            }
7394            for (int i=0; i<res.key.allIntents.length; i++) {
7395                Intent intent = res.key.allIntents[i];
7396                if (intent.getPackage() != null && intent.getComponent() != null) {
7397                    return false;
7398                }
7399            }
7400            return true;
7401        } catch (ClassCastException e) {
7402        }
7403        return false;
7404    }
7405
7406    @Override
7407    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7408        if (!(pendingResult instanceof PendingIntentRecord)) {
7409            return false;
7410        }
7411        try {
7412            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7413            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7414                return true;
7415            }
7416            return false;
7417        } catch (ClassCastException e) {
7418        }
7419        return false;
7420    }
7421
7422    @Override
7423    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7424        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7425                "getIntentForIntentSender()");
7426        if (!(pendingResult instanceof PendingIntentRecord)) {
7427            return null;
7428        }
7429        try {
7430            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7431            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7432        } catch (ClassCastException e) {
7433        }
7434        return null;
7435    }
7436
7437    @Override
7438    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7439        if (!(pendingResult instanceof PendingIntentRecord)) {
7440            return null;
7441        }
7442        try {
7443            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7444            synchronized (this) {
7445                return getTagForIntentSenderLocked(res, prefix);
7446            }
7447        } catch (ClassCastException e) {
7448        }
7449        return null;
7450    }
7451
7452    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7453        final Intent intent = res.key.requestIntent;
7454        if (intent != null) {
7455            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7456                    || res.lastTagPrefix.equals(prefix))) {
7457                return res.lastTag;
7458            }
7459            res.lastTagPrefix = prefix;
7460            final StringBuilder sb = new StringBuilder(128);
7461            if (prefix != null) {
7462                sb.append(prefix);
7463            }
7464            if (intent.getAction() != null) {
7465                sb.append(intent.getAction());
7466            } else if (intent.getComponent() != null) {
7467                intent.getComponent().appendShortString(sb);
7468            } else {
7469                sb.append("?");
7470            }
7471            return res.lastTag = sb.toString();
7472        }
7473        return null;
7474    }
7475
7476    @Override
7477    public void setProcessLimit(int max) {
7478        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7479                "setProcessLimit()");
7480        synchronized (this) {
7481            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7482            mProcessLimitOverride = max;
7483        }
7484        trimApplications();
7485    }
7486
7487    @Override
7488    public int getProcessLimit() {
7489        synchronized (this) {
7490            return mProcessLimitOverride;
7491        }
7492    }
7493
7494    void foregroundTokenDied(ForegroundToken token) {
7495        synchronized (ActivityManagerService.this) {
7496            synchronized (mPidsSelfLocked) {
7497                ForegroundToken cur
7498                    = mForegroundProcesses.get(token.pid);
7499                if (cur != token) {
7500                    return;
7501                }
7502                mForegroundProcesses.remove(token.pid);
7503                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7504                if (pr == null) {
7505                    return;
7506                }
7507                pr.forcingToForeground = null;
7508                updateProcessForegroundLocked(pr, false, false);
7509            }
7510            updateOomAdjLocked();
7511        }
7512    }
7513
7514    @Override
7515    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7516        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7517                "setProcessForeground()");
7518        synchronized(this) {
7519            boolean changed = false;
7520
7521            synchronized (mPidsSelfLocked) {
7522                ProcessRecord pr = mPidsSelfLocked.get(pid);
7523                if (pr == null && isForeground) {
7524                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7525                    return;
7526                }
7527                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7528                if (oldToken != null) {
7529                    oldToken.token.unlinkToDeath(oldToken, 0);
7530                    mForegroundProcesses.remove(pid);
7531                    if (pr != null) {
7532                        pr.forcingToForeground = null;
7533                    }
7534                    changed = true;
7535                }
7536                if (isForeground && token != null) {
7537                    ForegroundToken newToken = new ForegroundToken() {
7538                        @Override
7539                        public void binderDied() {
7540                            foregroundTokenDied(this);
7541                        }
7542                    };
7543                    newToken.pid = pid;
7544                    newToken.token = token;
7545                    try {
7546                        token.linkToDeath(newToken, 0);
7547                        mForegroundProcesses.put(pid, newToken);
7548                        pr.forcingToForeground = token;
7549                        changed = true;
7550                    } catch (RemoteException e) {
7551                        // If the process died while doing this, we will later
7552                        // do the cleanup with the process death link.
7553                    }
7554                }
7555            }
7556
7557            if (changed) {
7558                updateOomAdjLocked();
7559            }
7560        }
7561    }
7562
7563    @Override
7564    public boolean isAppForeground(int uid) throws RemoteException {
7565        synchronized (this) {
7566            UidRecord uidRec = mActiveUids.get(uid);
7567            if (uidRec == null || uidRec.idle) {
7568                return false;
7569            }
7570            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7571        }
7572    }
7573
7574    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7575    // be guarded by permission checking.
7576    int getUidState(int uid) {
7577        synchronized (this) {
7578            UidRecord uidRec = mActiveUids.get(uid);
7579            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7580        }
7581    }
7582
7583    @Override
7584    public boolean isInMultiWindowMode(IBinder token) {
7585        final long origId = Binder.clearCallingIdentity();
7586        try {
7587            synchronized(this) {
7588                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7589                if (r == null) {
7590                    return false;
7591                }
7592                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7593                return !r.task.mFullscreen;
7594            }
7595        } finally {
7596            Binder.restoreCallingIdentity(origId);
7597        }
7598    }
7599
7600    @Override
7601    public boolean isInPictureInPictureMode(IBinder token) {
7602        final long origId = Binder.clearCallingIdentity();
7603        try {
7604            synchronized(this) {
7605                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7606                if (stack == null) {
7607                    return false;
7608                }
7609                return stack.mStackId == PINNED_STACK_ID;
7610            }
7611        } finally {
7612            Binder.restoreCallingIdentity(origId);
7613        }
7614    }
7615
7616    @Override
7617    public void enterPictureInPictureMode(IBinder token) {
7618        final long origId = Binder.clearCallingIdentity();
7619        try {
7620            synchronized(this) {
7621                if (!mSupportsPictureInPicture) {
7622                    throw new IllegalStateException("enterPictureInPictureMode: "
7623                            + "Device doesn't support picture-in-picture mode.");
7624                }
7625
7626                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7627
7628                if (r == null) {
7629                    throw new IllegalStateException("enterPictureInPictureMode: "
7630                            + "Can't find activity for token=" + token);
7631                }
7632
7633                if (!r.supportsPictureInPicture()) {
7634                    throw new IllegalArgumentException("enterPictureInPictureMode: "
7635                            + "Picture-In-Picture not supported for r=" + r);
7636                }
7637
7638                // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
7639                // current bounds.
7640                final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
7641                final Rect bounds = (pinnedStack != null)
7642                        ? pinnedStack.mBounds : mDefaultPinnedStackBounds;
7643
7644                mStackSupervisor.moveActivityToPinnedStackLocked(
7645                        r, "enterPictureInPictureMode", bounds);
7646            }
7647        } finally {
7648            Binder.restoreCallingIdentity(origId);
7649        }
7650    }
7651
7652    // =========================================================
7653    // PROCESS INFO
7654    // =========================================================
7655
7656    static class ProcessInfoService extends IProcessInfoService.Stub {
7657        final ActivityManagerService mActivityManagerService;
7658        ProcessInfoService(ActivityManagerService activityManagerService) {
7659            mActivityManagerService = activityManagerService;
7660        }
7661
7662        @Override
7663        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7664            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7665                    /*in*/ pids, /*out*/ states, null);
7666        }
7667
7668        @Override
7669        public void getProcessStatesAndOomScoresFromPids(
7670                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7671            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7672                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7673        }
7674    }
7675
7676    /**
7677     * For each PID in the given input array, write the current process state
7678     * for that process into the states array, or -1 to indicate that no
7679     * process with the given PID exists. If scores array is provided, write
7680     * the oom score for the process into the scores array, with INVALID_ADJ
7681     * indicating the PID doesn't exist.
7682     */
7683    public void getProcessStatesAndOomScoresForPIDs(
7684            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7685        if (scores != null) {
7686            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7687                    "getProcessStatesAndOomScoresForPIDs()");
7688        }
7689
7690        if (pids == null) {
7691            throw new NullPointerException("pids");
7692        } else if (states == null) {
7693            throw new NullPointerException("states");
7694        } else if (pids.length != states.length) {
7695            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7696        } else if (scores != null && pids.length != scores.length) {
7697            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7698        }
7699
7700        synchronized (mPidsSelfLocked) {
7701            for (int i = 0; i < pids.length; i++) {
7702                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7703                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7704                        pr.curProcState;
7705                if (scores != null) {
7706                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7707                }
7708            }
7709        }
7710    }
7711
7712    // =========================================================
7713    // PERMISSIONS
7714    // =========================================================
7715
7716    static class PermissionController extends IPermissionController.Stub {
7717        ActivityManagerService mActivityManagerService;
7718        PermissionController(ActivityManagerService activityManagerService) {
7719            mActivityManagerService = activityManagerService;
7720        }
7721
7722        @Override
7723        public boolean checkPermission(String permission, int pid, int uid) {
7724            return mActivityManagerService.checkPermission(permission, pid,
7725                    uid) == PackageManager.PERMISSION_GRANTED;
7726        }
7727
7728        @Override
7729        public String[] getPackagesForUid(int uid) {
7730            return mActivityManagerService.mContext.getPackageManager()
7731                    .getPackagesForUid(uid);
7732        }
7733
7734        @Override
7735        public boolean isRuntimePermission(String permission) {
7736            try {
7737                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7738                        .getPermissionInfo(permission, 0);
7739                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7740            } catch (NameNotFoundException nnfe) {
7741                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7742            }
7743            return false;
7744        }
7745    }
7746
7747    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7748        @Override
7749        public int checkComponentPermission(String permission, int pid, int uid,
7750                int owningUid, boolean exported) {
7751            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7752                    owningUid, exported);
7753        }
7754
7755        @Override
7756        public Object getAMSLock() {
7757            return ActivityManagerService.this;
7758        }
7759    }
7760
7761    /**
7762     * This can be called with or without the global lock held.
7763     */
7764    int checkComponentPermission(String permission, int pid, int uid,
7765            int owningUid, boolean exported) {
7766        if (pid == MY_PID) {
7767            return PackageManager.PERMISSION_GRANTED;
7768        }
7769        return ActivityManager.checkComponentPermission(permission, uid,
7770                owningUid, exported);
7771    }
7772
7773    /**
7774     * As the only public entry point for permissions checking, this method
7775     * can enforce the semantic that requesting a check on a null global
7776     * permission is automatically denied.  (Internally a null permission
7777     * string is used when calling {@link #checkComponentPermission} in cases
7778     * when only uid-based security is needed.)
7779     *
7780     * This can be called with or without the global lock held.
7781     */
7782    @Override
7783    public int checkPermission(String permission, int pid, int uid) {
7784        if (permission == null) {
7785            return PackageManager.PERMISSION_DENIED;
7786        }
7787        return checkComponentPermission(permission, pid, uid, -1, true);
7788    }
7789
7790    @Override
7791    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7792        if (permission == null) {
7793            return PackageManager.PERMISSION_DENIED;
7794        }
7795
7796        // We might be performing an operation on behalf of an indirect binder
7797        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7798        // client identity accordingly before proceeding.
7799        Identity tlsIdentity = sCallerIdentity.get();
7800        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7801            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7802                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7803            uid = tlsIdentity.uid;
7804            pid = tlsIdentity.pid;
7805        }
7806
7807        return checkComponentPermission(permission, pid, uid, -1, true);
7808    }
7809
7810    /**
7811     * Binder IPC calls go through the public entry point.
7812     * This can be called with or without the global lock held.
7813     */
7814    int checkCallingPermission(String permission) {
7815        return checkPermission(permission,
7816                Binder.getCallingPid(),
7817                UserHandle.getAppId(Binder.getCallingUid()));
7818    }
7819
7820    /**
7821     * This can be called with or without the global lock held.
7822     */
7823    void enforceCallingPermission(String permission, String func) {
7824        if (checkCallingPermission(permission)
7825                == PackageManager.PERMISSION_GRANTED) {
7826            return;
7827        }
7828
7829        String msg = "Permission Denial: " + func + " from pid="
7830                + Binder.getCallingPid()
7831                + ", uid=" + Binder.getCallingUid()
7832                + " requires " + permission;
7833        Slog.w(TAG, msg);
7834        throw new SecurityException(msg);
7835    }
7836
7837    /**
7838     * Determine if UID is holding permissions required to access {@link Uri} in
7839     * the given {@link ProviderInfo}. Final permission checking is always done
7840     * in {@link ContentProvider}.
7841     */
7842    private final boolean checkHoldingPermissionsLocked(
7843            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7844        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7845                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7846        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7847            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7848                    != PERMISSION_GRANTED) {
7849                return false;
7850            }
7851        }
7852        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7853    }
7854
7855    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7856            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7857        if (pi.applicationInfo.uid == uid) {
7858            return true;
7859        } else if (!pi.exported) {
7860            return false;
7861        }
7862
7863        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7864        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7865        try {
7866            // check if target holds top-level <provider> permissions
7867            if (!readMet && pi.readPermission != null && considerUidPermissions
7868                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7869                readMet = true;
7870            }
7871            if (!writeMet && pi.writePermission != null && considerUidPermissions
7872                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7873                writeMet = true;
7874            }
7875
7876            // track if unprotected read/write is allowed; any denied
7877            // <path-permission> below removes this ability
7878            boolean allowDefaultRead = pi.readPermission == null;
7879            boolean allowDefaultWrite = pi.writePermission == null;
7880
7881            // check if target holds any <path-permission> that match uri
7882            final PathPermission[] pps = pi.pathPermissions;
7883            if (pps != null) {
7884                final String path = grantUri.uri.getPath();
7885                int i = pps.length;
7886                while (i > 0 && (!readMet || !writeMet)) {
7887                    i--;
7888                    PathPermission pp = pps[i];
7889                    if (pp.match(path)) {
7890                        if (!readMet) {
7891                            final String pprperm = pp.getReadPermission();
7892                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7893                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7894                                    + ": match=" + pp.match(path)
7895                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7896                            if (pprperm != null) {
7897                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7898                                        == PERMISSION_GRANTED) {
7899                                    readMet = true;
7900                                } else {
7901                                    allowDefaultRead = false;
7902                                }
7903                            }
7904                        }
7905                        if (!writeMet) {
7906                            final String ppwperm = pp.getWritePermission();
7907                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7908                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7909                                    + ": match=" + pp.match(path)
7910                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7911                            if (ppwperm != null) {
7912                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7913                                        == PERMISSION_GRANTED) {
7914                                    writeMet = true;
7915                                } else {
7916                                    allowDefaultWrite = false;
7917                                }
7918                            }
7919                        }
7920                    }
7921                }
7922            }
7923
7924            // grant unprotected <provider> read/write, if not blocked by
7925            // <path-permission> above
7926            if (allowDefaultRead) readMet = true;
7927            if (allowDefaultWrite) writeMet = true;
7928
7929        } catch (RemoteException e) {
7930            return false;
7931        }
7932
7933        return readMet && writeMet;
7934    }
7935
7936    public int getAppStartMode(int uid, String packageName) {
7937        synchronized (this) {
7938            return checkAllowBackgroundLocked(uid, packageName, -1, true);
7939        }
7940    }
7941
7942    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7943            boolean allowWhenForeground) {
7944        UidRecord uidRec = mActiveUids.get(uid);
7945        if (!mLenientBackgroundCheck) {
7946            if (!allowWhenForeground || uidRec == null
7947                    || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7948                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7949                        packageName) != AppOpsManager.MODE_ALLOWED) {
7950                    return ActivityManager.APP_START_MODE_DELAYED;
7951                }
7952            }
7953
7954        } else if (uidRec == null || uidRec.idle) {
7955            if (callingPid >= 0) {
7956                ProcessRecord proc;
7957                synchronized (mPidsSelfLocked) {
7958                    proc = mPidsSelfLocked.get(callingPid);
7959                }
7960                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7961                    // Whoever is instigating this is in the foreground, so we will allow it
7962                    // to go through.
7963                    return ActivityManager.APP_START_MODE_NORMAL;
7964                }
7965            }
7966            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7967                    != AppOpsManager.MODE_ALLOWED) {
7968                return ActivityManager.APP_START_MODE_DELAYED;
7969            }
7970        }
7971        return ActivityManager.APP_START_MODE_NORMAL;
7972    }
7973
7974    private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
7975        ProviderInfo pi = null;
7976        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7977        if (cpr != null) {
7978            pi = cpr.info;
7979        } else {
7980            try {
7981                pi = AppGlobals.getPackageManager().resolveContentProvider(
7982                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
7983                        userHandle);
7984            } catch (RemoteException ex) {
7985            }
7986        }
7987        return pi;
7988    }
7989
7990    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7991        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7992        if (targetUris != null) {
7993            return targetUris.get(grantUri);
7994        }
7995        return null;
7996    }
7997
7998    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7999            String targetPkg, int targetUid, GrantUri grantUri) {
8000        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8001        if (targetUris == null) {
8002            targetUris = Maps.newArrayMap();
8003            mGrantedUriPermissions.put(targetUid, targetUris);
8004        }
8005
8006        UriPermission perm = targetUris.get(grantUri);
8007        if (perm == null) {
8008            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
8009            targetUris.put(grantUri, perm);
8010        }
8011
8012        return perm;
8013    }
8014
8015    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
8016            final int modeFlags) {
8017        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
8018        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
8019                : UriPermission.STRENGTH_OWNED;
8020
8021        // Root gets to do everything.
8022        if (uid == 0) {
8023            return true;
8024        }
8025
8026        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8027        if (perms == null) return false;
8028
8029        // First look for exact match
8030        final UriPermission exactPerm = perms.get(grantUri);
8031        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
8032            return true;
8033        }
8034
8035        // No exact match, look for prefixes
8036        final int N = perms.size();
8037        for (int i = 0; i < N; i++) {
8038            final UriPermission perm = perms.valueAt(i);
8039            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
8040                    && perm.getStrength(modeFlags) >= minStrength) {
8041                return true;
8042            }
8043        }
8044
8045        return false;
8046    }
8047
8048    /**
8049     * @param uri This uri must NOT contain an embedded userId.
8050     * @param userId The userId in which the uri is to be resolved.
8051     */
8052    @Override
8053    public int checkUriPermission(Uri uri, int pid, int uid,
8054            final int modeFlags, int userId, IBinder callerToken) {
8055        enforceNotIsolatedCaller("checkUriPermission");
8056
8057        // Another redirected-binder-call permissions check as in
8058        // {@link checkPermissionWithToken}.
8059        Identity tlsIdentity = sCallerIdentity.get();
8060        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8061            uid = tlsIdentity.uid;
8062            pid = tlsIdentity.pid;
8063        }
8064
8065        // Our own process gets to do everything.
8066        if (pid == MY_PID) {
8067            return PackageManager.PERMISSION_GRANTED;
8068        }
8069        synchronized (this) {
8070            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
8071                    ? PackageManager.PERMISSION_GRANTED
8072                    : PackageManager.PERMISSION_DENIED;
8073        }
8074    }
8075
8076    /**
8077     * Check if the targetPkg can be granted permission to access uri by
8078     * the callingUid using the given modeFlags.  Throws a security exception
8079     * if callingUid is not allowed to do this.  Returns the uid of the target
8080     * if the URI permission grant should be performed; returns -1 if it is not
8081     * needed (for example targetPkg already has permission to access the URI).
8082     * If you already know the uid of the target, you can supply it in
8083     * lastTargetUid else set that to -1.
8084     */
8085    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8086            final int modeFlags, int lastTargetUid) {
8087        if (!Intent.isAccessUriMode(modeFlags)) {
8088            return -1;
8089        }
8090
8091        if (targetPkg != null) {
8092            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8093                    "Checking grant " + targetPkg + " permission to " + grantUri);
8094        }
8095
8096        final IPackageManager pm = AppGlobals.getPackageManager();
8097
8098        // If this is not a content: uri, we can't do anything with it.
8099        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8100            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8101                    "Can't grant URI permission for non-content URI: " + grantUri);
8102            return -1;
8103        }
8104
8105        final String authority = grantUri.uri.getAuthority();
8106        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8107                MATCH_DEBUG_TRIAGED_MISSING);
8108        if (pi == null) {
8109            Slog.w(TAG, "No content provider found for permission check: " +
8110                    grantUri.uri.toSafeString());
8111            return -1;
8112        }
8113
8114        int targetUid = lastTargetUid;
8115        if (targetUid < 0 && targetPkg != null) {
8116            try {
8117                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8118                        UserHandle.getUserId(callingUid));
8119                if (targetUid < 0) {
8120                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8121                            "Can't grant URI permission no uid for: " + targetPkg);
8122                    return -1;
8123                }
8124            } catch (RemoteException ex) {
8125                return -1;
8126            }
8127        }
8128
8129        if (targetUid >= 0) {
8130            // First...  does the target actually need this permission?
8131            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8132                // No need to grant the target this permission.
8133                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8134                        "Target " + targetPkg + " already has full permission to " + grantUri);
8135                return -1;
8136            }
8137        } else {
8138            // First...  there is no target package, so can anyone access it?
8139            boolean allowed = pi.exported;
8140            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8141                if (pi.readPermission != null) {
8142                    allowed = false;
8143                }
8144            }
8145            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8146                if (pi.writePermission != null) {
8147                    allowed = false;
8148                }
8149            }
8150            if (allowed) {
8151                return -1;
8152            }
8153        }
8154
8155        /* There is a special cross user grant if:
8156         * - The target is on another user.
8157         * - Apps on the current user can access the uri without any uid permissions.
8158         * In this case, we grant a uri permission, even if the ContentProvider does not normally
8159         * grant uri permissions.
8160         */
8161        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8162                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8163                modeFlags, false /*without considering the uid permissions*/);
8164
8165        // Second...  is the provider allowing granting of URI permissions?
8166        if (!specialCrossUserGrant) {
8167            if (!pi.grantUriPermissions) {
8168                throw new SecurityException("Provider " + pi.packageName
8169                        + "/" + pi.name
8170                        + " does not allow granting of Uri permissions (uri "
8171                        + grantUri + ")");
8172            }
8173            if (pi.uriPermissionPatterns != null) {
8174                final int N = pi.uriPermissionPatterns.length;
8175                boolean allowed = false;
8176                for (int i=0; i<N; i++) {
8177                    if (pi.uriPermissionPatterns[i] != null
8178                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8179                        allowed = true;
8180                        break;
8181                    }
8182                }
8183                if (!allowed) {
8184                    throw new SecurityException("Provider " + pi.packageName
8185                            + "/" + pi.name
8186                            + " does not allow granting of permission to path of Uri "
8187                            + grantUri);
8188                }
8189            }
8190        }
8191
8192        // Third...  does the caller itself have permission to access
8193        // this uri?
8194        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
8195            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8196                // Require they hold a strong enough Uri permission
8197                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8198                    throw new SecurityException("Uid " + callingUid
8199                            + " does not have permission to uri " + grantUri);
8200                }
8201            }
8202        }
8203        return targetUid;
8204    }
8205
8206    /**
8207     * @param uri This uri must NOT contain an embedded userId.
8208     * @param userId The userId in which the uri is to be resolved.
8209     */
8210    @Override
8211    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8212            final int modeFlags, int userId) {
8213        enforceNotIsolatedCaller("checkGrantUriPermission");
8214        synchronized(this) {
8215            return checkGrantUriPermissionLocked(callingUid, targetPkg,
8216                    new GrantUri(userId, uri, false), modeFlags, -1);
8217        }
8218    }
8219
8220    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8221            final int modeFlags, UriPermissionOwner owner) {
8222        if (!Intent.isAccessUriMode(modeFlags)) {
8223            return;
8224        }
8225
8226        // So here we are: the caller has the assumed permission
8227        // to the uri, and the target doesn't.  Let's now give this to
8228        // the target.
8229
8230        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8231                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8232
8233        final String authority = grantUri.uri.getAuthority();
8234        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8235                MATCH_DEBUG_TRIAGED_MISSING);
8236        if (pi == null) {
8237            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8238            return;
8239        }
8240
8241        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8242            grantUri.prefix = true;
8243        }
8244        final UriPermission perm = findOrCreateUriPermissionLocked(
8245                pi.packageName, targetPkg, targetUid, grantUri);
8246        perm.grantModes(modeFlags, owner);
8247    }
8248
8249    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8250            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8251        if (targetPkg == null) {
8252            throw new NullPointerException("targetPkg");
8253        }
8254        int targetUid;
8255        final IPackageManager pm = AppGlobals.getPackageManager();
8256        try {
8257            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8258        } catch (RemoteException ex) {
8259            return;
8260        }
8261
8262        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8263                targetUid);
8264        if (targetUid < 0) {
8265            return;
8266        }
8267
8268        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8269                owner);
8270    }
8271
8272    static class NeededUriGrants extends ArrayList<GrantUri> {
8273        final String targetPkg;
8274        final int targetUid;
8275        final int flags;
8276
8277        NeededUriGrants(String targetPkg, int targetUid, int flags) {
8278            this.targetPkg = targetPkg;
8279            this.targetUid = targetUid;
8280            this.flags = flags;
8281        }
8282    }
8283
8284    /**
8285     * Like checkGrantUriPermissionLocked, but takes an Intent.
8286     */
8287    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8288            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8289        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8290                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8291                + " clip=" + (intent != null ? intent.getClipData() : null)
8292                + " from " + intent + "; flags=0x"
8293                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8294
8295        if (targetPkg == null) {
8296            throw new NullPointerException("targetPkg");
8297        }
8298
8299        if (intent == null) {
8300            return null;
8301        }
8302        Uri data = intent.getData();
8303        ClipData clip = intent.getClipData();
8304        if (data == null && clip == null) {
8305            return null;
8306        }
8307        // Default userId for uris in the intent (if they don't specify it themselves)
8308        int contentUserHint = intent.getContentUserHint();
8309        if (contentUserHint == UserHandle.USER_CURRENT) {
8310            contentUserHint = UserHandle.getUserId(callingUid);
8311        }
8312        final IPackageManager pm = AppGlobals.getPackageManager();
8313        int targetUid;
8314        if (needed != null) {
8315            targetUid = needed.targetUid;
8316        } else {
8317            try {
8318                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8319                        targetUserId);
8320            } catch (RemoteException ex) {
8321                return null;
8322            }
8323            if (targetUid < 0) {
8324                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8325                        "Can't grant URI permission no uid for: " + targetPkg
8326                        + " on user " + targetUserId);
8327                return null;
8328            }
8329        }
8330        if (data != null) {
8331            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8332            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8333                    targetUid);
8334            if (targetUid > 0) {
8335                if (needed == null) {
8336                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8337                }
8338                needed.add(grantUri);
8339            }
8340        }
8341        if (clip != null) {
8342            for (int i=0; i<clip.getItemCount(); i++) {
8343                Uri uri = clip.getItemAt(i).getUri();
8344                if (uri != null) {
8345                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8346                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8347                            targetUid);
8348                    if (targetUid > 0) {
8349                        if (needed == null) {
8350                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8351                        }
8352                        needed.add(grantUri);
8353                    }
8354                } else {
8355                    Intent clipIntent = clip.getItemAt(i).getIntent();
8356                    if (clipIntent != null) {
8357                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8358                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8359                        if (newNeeded != null) {
8360                            needed = newNeeded;
8361                        }
8362                    }
8363                }
8364            }
8365        }
8366
8367        return needed;
8368    }
8369
8370    /**
8371     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8372     */
8373    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8374            UriPermissionOwner owner) {
8375        if (needed != null) {
8376            for (int i=0; i<needed.size(); i++) {
8377                GrantUri grantUri = needed.get(i);
8378                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8379                        grantUri, needed.flags, owner);
8380            }
8381        }
8382    }
8383
8384    void grantUriPermissionFromIntentLocked(int callingUid,
8385            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8386        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8387                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8388        if (needed == null) {
8389            return;
8390        }
8391
8392        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8393    }
8394
8395    /**
8396     * @param uri This uri must NOT contain an embedded userId.
8397     * @param userId The userId in which the uri is to be resolved.
8398     */
8399    @Override
8400    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8401            final int modeFlags, int userId) {
8402        enforceNotIsolatedCaller("grantUriPermission");
8403        GrantUri grantUri = new GrantUri(userId, uri, false);
8404        synchronized(this) {
8405            final ProcessRecord r = getRecordForAppLocked(caller);
8406            if (r == null) {
8407                throw new SecurityException("Unable to find app for caller "
8408                        + caller
8409                        + " when granting permission to uri " + grantUri);
8410            }
8411            if (targetPkg == null) {
8412                throw new IllegalArgumentException("null target");
8413            }
8414            if (grantUri == null) {
8415                throw new IllegalArgumentException("null uri");
8416            }
8417
8418            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8419                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8420                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8421                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8422
8423            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8424                    UserHandle.getUserId(r.uid));
8425        }
8426    }
8427
8428    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8429        if (perm.modeFlags == 0) {
8430            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8431                    perm.targetUid);
8432            if (perms != null) {
8433                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8434                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8435
8436                perms.remove(perm.uri);
8437                if (perms.isEmpty()) {
8438                    mGrantedUriPermissions.remove(perm.targetUid);
8439                }
8440            }
8441        }
8442    }
8443
8444    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8445        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8446                "Revoking all granted permissions to " + grantUri);
8447
8448        final IPackageManager pm = AppGlobals.getPackageManager();
8449        final String authority = grantUri.uri.getAuthority();
8450        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8451                MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8452        if (pi == null) {
8453            Slog.w(TAG, "No content provider found for permission revoke: "
8454                    + grantUri.toSafeString());
8455            return;
8456        }
8457
8458        // Does the caller have this permission on the URI?
8459        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8460            // If they don't have direct access to the URI, then revoke any
8461            // ownerless URI permissions that have been granted to them.
8462            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8463            if (perms != null) {
8464                boolean persistChanged = false;
8465                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8466                    final UriPermission perm = it.next();
8467                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8468                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8469                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8470                                "Revoking non-owned " + perm.targetUid
8471                                + " permission to " + perm.uri);
8472                        persistChanged |= perm.revokeModes(
8473                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8474                        if (perm.modeFlags == 0) {
8475                            it.remove();
8476                        }
8477                    }
8478                }
8479                if (perms.isEmpty()) {
8480                    mGrantedUriPermissions.remove(callingUid);
8481                }
8482                if (persistChanged) {
8483                    schedulePersistUriGrants();
8484                }
8485            }
8486            return;
8487        }
8488
8489        boolean persistChanged = false;
8490
8491        // Go through all of the permissions and remove any that match.
8492        int N = mGrantedUriPermissions.size();
8493        for (int i = 0; i < N; i++) {
8494            final int targetUid = mGrantedUriPermissions.keyAt(i);
8495            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8496
8497            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8498                final UriPermission perm = it.next();
8499                if (perm.uri.sourceUserId == grantUri.sourceUserId
8500                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8501                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8502                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8503                    persistChanged |= perm.revokeModes(
8504                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8505                    if (perm.modeFlags == 0) {
8506                        it.remove();
8507                    }
8508                }
8509            }
8510
8511            if (perms.isEmpty()) {
8512                mGrantedUriPermissions.remove(targetUid);
8513                N--;
8514                i--;
8515            }
8516        }
8517
8518        if (persistChanged) {
8519            schedulePersistUriGrants();
8520        }
8521    }
8522
8523    /**
8524     * @param uri This uri must NOT contain an embedded userId.
8525     * @param userId The userId in which the uri is to be resolved.
8526     */
8527    @Override
8528    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8529            int userId) {
8530        enforceNotIsolatedCaller("revokeUriPermission");
8531        synchronized(this) {
8532            final ProcessRecord r = getRecordForAppLocked(caller);
8533            if (r == null) {
8534                throw new SecurityException("Unable to find app for caller "
8535                        + caller
8536                        + " when revoking permission to uri " + uri);
8537            }
8538            if (uri == null) {
8539                Slog.w(TAG, "revokeUriPermission: null uri");
8540                return;
8541            }
8542
8543            if (!Intent.isAccessUriMode(modeFlags)) {
8544                return;
8545            }
8546
8547            final String authority = uri.getAuthority();
8548            final ProviderInfo pi = getProviderInfoLocked(authority, userId,
8549                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8550            if (pi == null) {
8551                Slog.w(TAG, "No content provider found for permission revoke: "
8552                        + uri.toSafeString());
8553                return;
8554            }
8555
8556            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8557        }
8558    }
8559
8560    /**
8561     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8562     * given package.
8563     *
8564     * @param packageName Package name to match, or {@code null} to apply to all
8565     *            packages.
8566     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8567     *            to all users.
8568     * @param persistable If persistable grants should be removed.
8569     */
8570    private void removeUriPermissionsForPackageLocked(
8571            String packageName, int userHandle, boolean persistable) {
8572        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8573            throw new IllegalArgumentException("Must narrow by either package or user");
8574        }
8575
8576        boolean persistChanged = false;
8577
8578        int N = mGrantedUriPermissions.size();
8579        for (int i = 0; i < N; i++) {
8580            final int targetUid = mGrantedUriPermissions.keyAt(i);
8581            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8582
8583            // Only inspect grants matching user
8584            if (userHandle == UserHandle.USER_ALL
8585                    || userHandle == UserHandle.getUserId(targetUid)) {
8586                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8587                    final UriPermission perm = it.next();
8588
8589                    // Only inspect grants matching package
8590                    if (packageName == null || perm.sourcePkg.equals(packageName)
8591                            || perm.targetPkg.equals(packageName)) {
8592                        persistChanged |= perm.revokeModes(persistable
8593                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8594
8595                        // Only remove when no modes remain; any persisted grants
8596                        // will keep this alive.
8597                        if (perm.modeFlags == 0) {
8598                            it.remove();
8599                        }
8600                    }
8601                }
8602
8603                if (perms.isEmpty()) {
8604                    mGrantedUriPermissions.remove(targetUid);
8605                    N--;
8606                    i--;
8607                }
8608            }
8609        }
8610
8611        if (persistChanged) {
8612            schedulePersistUriGrants();
8613        }
8614    }
8615
8616    @Override
8617    public IBinder newUriPermissionOwner(String name) {
8618        enforceNotIsolatedCaller("newUriPermissionOwner");
8619        synchronized(this) {
8620            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8621            return owner.getExternalTokenLocked();
8622        }
8623    }
8624
8625    @Override
8626    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8627        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8628        synchronized(this) {
8629            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8630            if (r == null) {
8631                throw new IllegalArgumentException("Activity does not exist; token="
8632                        + activityToken);
8633            }
8634            return r.getUriPermissionsLocked().getExternalTokenLocked();
8635        }
8636    }
8637    /**
8638     * @param uri This uri must NOT contain an embedded userId.
8639     * @param sourceUserId The userId in which the uri is to be resolved.
8640     * @param targetUserId The userId of the app that receives the grant.
8641     */
8642    @Override
8643    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8644            final int modeFlags, int sourceUserId, int targetUserId) {
8645        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8646                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8647                "grantUriPermissionFromOwner", null);
8648        synchronized(this) {
8649            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8650            if (owner == null) {
8651                throw new IllegalArgumentException("Unknown owner: " + token);
8652            }
8653            if (fromUid != Binder.getCallingUid()) {
8654                if (Binder.getCallingUid() != Process.myUid()) {
8655                    // Only system code can grant URI permissions on behalf
8656                    // of other users.
8657                    throw new SecurityException("nice try");
8658                }
8659            }
8660            if (targetPkg == null) {
8661                throw new IllegalArgumentException("null target");
8662            }
8663            if (uri == null) {
8664                throw new IllegalArgumentException("null uri");
8665            }
8666
8667            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8668                    modeFlags, owner, targetUserId);
8669        }
8670    }
8671
8672    /**
8673     * @param uri This uri must NOT contain an embedded userId.
8674     * @param userId The userId in which the uri is to be resolved.
8675     */
8676    @Override
8677    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8678        synchronized(this) {
8679            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8680            if (owner == null) {
8681                throw new IllegalArgumentException("Unknown owner: " + token);
8682            }
8683
8684            if (uri == null) {
8685                owner.removeUriPermissionsLocked(mode);
8686            } else {
8687                final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
8688                owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
8689            }
8690        }
8691    }
8692
8693    private void schedulePersistUriGrants() {
8694        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8695            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8696                    10 * DateUtils.SECOND_IN_MILLIS);
8697        }
8698    }
8699
8700    private void writeGrantedUriPermissions() {
8701        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8702
8703        // Snapshot permissions so we can persist without lock
8704        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8705        synchronized (this) {
8706            final int size = mGrantedUriPermissions.size();
8707            for (int i = 0; i < size; i++) {
8708                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8709                for (UriPermission perm : perms.values()) {
8710                    if (perm.persistedModeFlags != 0) {
8711                        persist.add(perm.snapshot());
8712                    }
8713                }
8714            }
8715        }
8716
8717        FileOutputStream fos = null;
8718        try {
8719            fos = mGrantFile.startWrite();
8720
8721            XmlSerializer out = new FastXmlSerializer();
8722            out.setOutput(fos, StandardCharsets.UTF_8.name());
8723            out.startDocument(null, true);
8724            out.startTag(null, TAG_URI_GRANTS);
8725            for (UriPermission.Snapshot perm : persist) {
8726                out.startTag(null, TAG_URI_GRANT);
8727                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8728                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8729                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8730                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8731                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8732                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8733                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8734                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8735                out.endTag(null, TAG_URI_GRANT);
8736            }
8737            out.endTag(null, TAG_URI_GRANTS);
8738            out.endDocument();
8739
8740            mGrantFile.finishWrite(fos);
8741        } catch (IOException e) {
8742            if (fos != null) {
8743                mGrantFile.failWrite(fos);
8744            }
8745        }
8746    }
8747
8748    private void readGrantedUriPermissionsLocked() {
8749        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8750
8751        final long now = System.currentTimeMillis();
8752
8753        FileInputStream fis = null;
8754        try {
8755            fis = mGrantFile.openRead();
8756            final XmlPullParser in = Xml.newPullParser();
8757            in.setInput(fis, StandardCharsets.UTF_8.name());
8758
8759            int type;
8760            while ((type = in.next()) != END_DOCUMENT) {
8761                final String tag = in.getName();
8762                if (type == START_TAG) {
8763                    if (TAG_URI_GRANT.equals(tag)) {
8764                        final int sourceUserId;
8765                        final int targetUserId;
8766                        final int userHandle = readIntAttribute(in,
8767                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8768                        if (userHandle != UserHandle.USER_NULL) {
8769                            // For backwards compatibility.
8770                            sourceUserId = userHandle;
8771                            targetUserId = userHandle;
8772                        } else {
8773                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8774                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8775                        }
8776                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8777                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8778                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8779                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8780                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8781                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8782
8783                        // Sanity check that provider still belongs to source package
8784                        // Both direct boot aware and unaware packages are fine as we
8785                        // will do filtering at query time to avoid multiple parsing.
8786                        final ProviderInfo pi = getProviderInfoLocked(
8787                                uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
8788                                        | MATCH_DIRECT_BOOT_UNAWARE);
8789                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8790                            int targetUid = -1;
8791                            try {
8792                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8793                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8794                            } catch (RemoteException e) {
8795                            }
8796                            if (targetUid != -1) {
8797                                final UriPermission perm = findOrCreateUriPermissionLocked(
8798                                        sourcePkg, targetPkg, targetUid,
8799                                        new GrantUri(sourceUserId, uri, prefix));
8800                                perm.initPersistedModes(modeFlags, createdTime);
8801                            }
8802                        } else {
8803                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8804                                    + " but instead found " + pi);
8805                        }
8806                    }
8807                }
8808            }
8809        } catch (FileNotFoundException e) {
8810            // Missing grants is okay
8811        } catch (IOException e) {
8812            Slog.wtf(TAG, "Failed reading Uri grants", e);
8813        } catch (XmlPullParserException e) {
8814            Slog.wtf(TAG, "Failed reading Uri grants", e);
8815        } finally {
8816            IoUtils.closeQuietly(fis);
8817        }
8818    }
8819
8820    /**
8821     * @param uri This uri must NOT contain an embedded userId.
8822     * @param userId The userId in which the uri is to be resolved.
8823     */
8824    @Override
8825    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8826        enforceNotIsolatedCaller("takePersistableUriPermission");
8827
8828        Preconditions.checkFlagsArgument(modeFlags,
8829                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8830
8831        synchronized (this) {
8832            final int callingUid = Binder.getCallingUid();
8833            boolean persistChanged = false;
8834            GrantUri grantUri = new GrantUri(userId, uri, false);
8835
8836            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8837                    new GrantUri(userId, uri, false));
8838            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8839                    new GrantUri(userId, uri, true));
8840
8841            final boolean exactValid = (exactPerm != null)
8842                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8843            final boolean prefixValid = (prefixPerm != null)
8844                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8845
8846            if (!(exactValid || prefixValid)) {
8847                throw new SecurityException("No persistable permission grants found for UID "
8848                        + callingUid + " and Uri " + grantUri.toSafeString());
8849            }
8850
8851            if (exactValid) {
8852                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8853            }
8854            if (prefixValid) {
8855                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8856            }
8857
8858            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8859
8860            if (persistChanged) {
8861                schedulePersistUriGrants();
8862            }
8863        }
8864    }
8865
8866    /**
8867     * @param uri This uri must NOT contain an embedded userId.
8868     * @param userId The userId in which the uri is to be resolved.
8869     */
8870    @Override
8871    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8872        enforceNotIsolatedCaller("releasePersistableUriPermission");
8873
8874        Preconditions.checkFlagsArgument(modeFlags,
8875                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8876
8877        synchronized (this) {
8878            final int callingUid = Binder.getCallingUid();
8879            boolean persistChanged = false;
8880
8881            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8882                    new GrantUri(userId, uri, false));
8883            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8884                    new GrantUri(userId, uri, true));
8885            if (exactPerm == null && prefixPerm == null) {
8886                throw new SecurityException("No permission grants found for UID " + callingUid
8887                        + " and Uri " + uri.toSafeString());
8888            }
8889
8890            if (exactPerm != null) {
8891                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8892                removeUriPermissionIfNeededLocked(exactPerm);
8893            }
8894            if (prefixPerm != null) {
8895                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8896                removeUriPermissionIfNeededLocked(prefixPerm);
8897            }
8898
8899            if (persistChanged) {
8900                schedulePersistUriGrants();
8901            }
8902        }
8903    }
8904
8905    /**
8906     * Prune any older {@link UriPermission} for the given UID until outstanding
8907     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8908     *
8909     * @return if any mutations occured that require persisting.
8910     */
8911    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8912        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8913        if (perms == null) return false;
8914        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8915
8916        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8917        for (UriPermission perm : perms.values()) {
8918            if (perm.persistedModeFlags != 0) {
8919                persisted.add(perm);
8920            }
8921        }
8922
8923        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8924        if (trimCount <= 0) return false;
8925
8926        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8927        for (int i = 0; i < trimCount; i++) {
8928            final UriPermission perm = persisted.get(i);
8929
8930            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8931                    "Trimming grant created at " + perm.persistedCreateTime);
8932
8933            perm.releasePersistableModes(~0);
8934            removeUriPermissionIfNeededLocked(perm);
8935        }
8936
8937        return true;
8938    }
8939
8940    @Override
8941    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8942            String packageName, boolean incoming) {
8943        enforceNotIsolatedCaller("getPersistedUriPermissions");
8944        Preconditions.checkNotNull(packageName, "packageName");
8945
8946        final int callingUid = Binder.getCallingUid();
8947        final int callingUserId = UserHandle.getUserId(callingUid);
8948        final IPackageManager pm = AppGlobals.getPackageManager();
8949        try {
8950            final int packageUid = pm.getPackageUid(packageName,
8951                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
8952            if (packageUid != callingUid) {
8953                throw new SecurityException(
8954                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8955            }
8956        } catch (RemoteException e) {
8957            throw new SecurityException("Failed to verify package name ownership");
8958        }
8959
8960        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8961        synchronized (this) {
8962            if (incoming) {
8963                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8964                        callingUid);
8965                if (perms == null) {
8966                    Slog.w(TAG, "No permission grants found for " + packageName);
8967                } else {
8968                    for (UriPermission perm : perms.values()) {
8969                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8970                            result.add(perm.buildPersistedPublicApiObject());
8971                        }
8972                    }
8973                }
8974            } else {
8975                final int size = mGrantedUriPermissions.size();
8976                for (int i = 0; i < size; i++) {
8977                    final ArrayMap<GrantUri, UriPermission> perms =
8978                            mGrantedUriPermissions.valueAt(i);
8979                    for (UriPermission perm : perms.values()) {
8980                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8981                            result.add(perm.buildPersistedPublicApiObject());
8982                        }
8983                    }
8984                }
8985            }
8986        }
8987        return new ParceledListSlice<android.content.UriPermission>(result);
8988    }
8989
8990    @Override
8991    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8992            String packageName, int userId) {
8993        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8994                "getGrantedUriPermissions");
8995
8996        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8997        synchronized (this) {
8998            final int size = mGrantedUriPermissions.size();
8999            for (int i = 0; i < size; i++) {
9000                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9001                for (UriPermission perm : perms.values()) {
9002                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
9003                            && perm.persistedModeFlags != 0) {
9004                        result.add(perm.buildPersistedPublicApiObject());
9005                    }
9006                }
9007            }
9008        }
9009        return new ParceledListSlice<android.content.UriPermission>(result);
9010    }
9011
9012    @Override
9013    public void clearGrantedUriPermissions(String packageName, int userId) {
9014        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
9015                "clearGrantedUriPermissions");
9016        removeUriPermissionsForPackageLocked(packageName, userId, true);
9017    }
9018
9019    @Override
9020    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
9021        synchronized (this) {
9022            ProcessRecord app =
9023                who != null ? getRecordForAppLocked(who) : null;
9024            if (app == null) return;
9025
9026            Message msg = Message.obtain();
9027            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
9028            msg.obj = app;
9029            msg.arg1 = waiting ? 1 : 0;
9030            mUiHandler.sendMessage(msg);
9031        }
9032    }
9033
9034    @Override
9035    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
9036        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
9037        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
9038        outInfo.availMem = Process.getFreeMemory();
9039        outInfo.totalMem = Process.getTotalMemory();
9040        outInfo.threshold = homeAppMem;
9041        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
9042        outInfo.hiddenAppThreshold = cachedAppMem;
9043        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
9044                ProcessList.SERVICE_ADJ);
9045        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
9046                ProcessList.VISIBLE_APP_ADJ);
9047        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
9048                ProcessList.FOREGROUND_APP_ADJ);
9049    }
9050
9051    // =========================================================
9052    // TASK MANAGEMENT
9053    // =========================================================
9054
9055    @Override
9056    public List<IAppTask> getAppTasks(String callingPackage) {
9057        int callingUid = Binder.getCallingUid();
9058        long ident = Binder.clearCallingIdentity();
9059
9060        synchronized(this) {
9061            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
9062            try {
9063                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
9064
9065                final int N = mRecentTasks.size();
9066                for (int i = 0; i < N; i++) {
9067                    TaskRecord tr = mRecentTasks.get(i);
9068                    // Skip tasks that do not match the caller.  We don't need to verify
9069                    // callingPackage, because we are also limiting to callingUid and know
9070                    // that will limit to the correct security sandbox.
9071                    if (tr.effectiveUid != callingUid) {
9072                        continue;
9073                    }
9074                    Intent intent = tr.getBaseIntent();
9075                    if (intent == null ||
9076                            !callingPackage.equals(intent.getComponent().getPackageName())) {
9077                        continue;
9078                    }
9079                    ActivityManager.RecentTaskInfo taskInfo =
9080                            createRecentTaskInfoFromTaskRecord(tr);
9081                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
9082                    list.add(taskImpl);
9083                }
9084            } finally {
9085                Binder.restoreCallingIdentity(ident);
9086            }
9087            return list;
9088        }
9089    }
9090
9091    @Override
9092    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9093        final int callingUid = Binder.getCallingUid();
9094        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9095
9096        synchronized(this) {
9097            if (DEBUG_ALL) Slog.v(
9098                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9099
9100            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9101                    callingUid);
9102
9103            // TODO: Improve with MRU list from all ActivityStacks.
9104            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9105        }
9106
9107        return list;
9108    }
9109
9110    /**
9111     * Creates a new RecentTaskInfo from a TaskRecord.
9112     */
9113    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9114        // Update the task description to reflect any changes in the task stack
9115        tr.updateTaskDescription();
9116
9117        // Compose the recent task info
9118        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9119        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9120        rti.persistentId = tr.taskId;
9121        rti.baseIntent = new Intent(tr.getBaseIntent());
9122        rti.origActivity = tr.origActivity;
9123        rti.realActivity = tr.realActivity;
9124        rti.description = tr.lastDescription;
9125        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
9126        rti.userId = tr.userId;
9127        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9128        rti.firstActiveTime = tr.firstActiveTime;
9129        rti.lastActiveTime = tr.lastActiveTime;
9130        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9131        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9132        rti.numActivities = 0;
9133        if (tr.mBounds != null) {
9134            rti.bounds = new Rect(tr.mBounds);
9135        }
9136        rti.isDockable = tr.canGoInDockedStack();
9137        rti.resizeMode = tr.mResizeMode;
9138
9139        ActivityRecord base = null;
9140        ActivityRecord top = null;
9141        ActivityRecord tmp;
9142
9143        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9144            tmp = tr.mActivities.get(i);
9145            if (tmp.finishing) {
9146                continue;
9147            }
9148            base = tmp;
9149            if (top == null || (top.state == ActivityState.INITIALIZING)) {
9150                top = base;
9151            }
9152            rti.numActivities++;
9153        }
9154
9155        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9156        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9157
9158        return rti;
9159    }
9160
9161    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9162        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9163                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9164        if (!allowed) {
9165            if (checkPermission(android.Manifest.permission.GET_TASKS,
9166                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9167                // Temporary compatibility: some existing apps on the system image may
9168                // still be requesting the old permission and not switched to the new
9169                // one; if so, we'll still allow them full access.  This means we need
9170                // to see if they are holding the old permission and are a system app.
9171                try {
9172                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9173                        allowed = true;
9174                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9175                                + " is using old GET_TASKS but privileged; allowing");
9176                    }
9177                } catch (RemoteException e) {
9178                }
9179            }
9180        }
9181        if (!allowed) {
9182            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9183                    + " does not hold REAL_GET_TASKS; limiting output");
9184        }
9185        return allowed;
9186    }
9187
9188    @Override
9189    public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9190            int userId) {
9191        final int callingUid = Binder.getCallingUid();
9192        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9193                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9194
9195        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9196        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9197        synchronized (this) {
9198            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9199                    callingUid);
9200            final boolean detailed = checkCallingPermission(
9201                    android.Manifest.permission.GET_DETAILED_TASKS)
9202                    == PackageManager.PERMISSION_GRANTED;
9203
9204            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9205                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9206                return ParceledListSlice.emptyList();
9207            }
9208            mRecentTasks.loadUserRecentsLocked(userId);
9209
9210            final int recentsCount = mRecentTasks.size();
9211            ArrayList<ActivityManager.RecentTaskInfo> res =
9212                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9213
9214            final Set<Integer> includedUsers;
9215            if (includeProfiles) {
9216                includedUsers = mUserController.getProfileIds(userId);
9217            } else {
9218                includedUsers = new HashSet<>();
9219            }
9220            includedUsers.add(Integer.valueOf(userId));
9221
9222            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9223                TaskRecord tr = mRecentTasks.get(i);
9224                // Only add calling user or related users recent tasks
9225                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9226                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9227                    continue;
9228                }
9229
9230                if (tr.realActivitySuspended) {
9231                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9232                    continue;
9233                }
9234
9235                // Return the entry if desired by the caller.  We always return
9236                // the first entry, because callers always expect this to be the
9237                // foreground app.  We may filter others if the caller has
9238                // not supplied RECENT_WITH_EXCLUDED and there is some reason
9239                // we should exclude the entry.
9240
9241                if (i == 0
9242                        || withExcluded
9243                        || (tr.intent == null)
9244                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9245                                == 0)) {
9246                    if (!allowed) {
9247                        // If the caller doesn't have the GET_TASKS permission, then only
9248                        // allow them to see a small subset of tasks -- their own and home.
9249                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9250                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9251                            continue;
9252                        }
9253                    }
9254                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
9255                        if (tr.stack != null && tr.stack.isHomeStack()) {
9256                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9257                                    "Skipping, home stack task: " + tr);
9258                            continue;
9259                        }
9260                    }
9261                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9262                        final ActivityStack stack = tr.stack;
9263                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9264                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9265                                    "Skipping, top task in docked stack: " + tr);
9266                            continue;
9267                        }
9268                    }
9269                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9270                        if (tr.stack != null && tr.stack.isPinnedStack()) {
9271                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9272                                    "Skipping, pinned stack task: " + tr);
9273                            continue;
9274                        }
9275                    }
9276                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9277                        // Don't include auto remove tasks that are finished or finishing.
9278                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9279                                "Skipping, auto-remove without activity: " + tr);
9280                        continue;
9281                    }
9282                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9283                            && !tr.isAvailable) {
9284                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9285                                "Skipping, unavail real act: " + tr);
9286                        continue;
9287                    }
9288
9289                    if (!tr.mUserSetupComplete) {
9290                        // Don't include task launched while user is not done setting-up.
9291                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9292                                "Skipping, user setup not complete: " + tr);
9293                        continue;
9294                    }
9295
9296                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9297                    if (!detailed) {
9298                        rti.baseIntent.replaceExtras((Bundle)null);
9299                    }
9300
9301                    res.add(rti);
9302                    maxNum--;
9303                }
9304            }
9305            return new ParceledListSlice<>(res);
9306        }
9307    }
9308
9309    @Override
9310    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9311        synchronized (this) {
9312            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9313                    "getTaskThumbnail()");
9314            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9315                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9316            if (tr != null) {
9317                return tr.getTaskThumbnailLocked();
9318            }
9319        }
9320        return null;
9321    }
9322
9323    @Override
9324    public int addAppTask(IBinder activityToken, Intent intent,
9325            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9326        final int callingUid = Binder.getCallingUid();
9327        final long callingIdent = Binder.clearCallingIdentity();
9328
9329        try {
9330            synchronized (this) {
9331                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9332                if (r == null) {
9333                    throw new IllegalArgumentException("Activity does not exist; token="
9334                            + activityToken);
9335                }
9336                ComponentName comp = intent.getComponent();
9337                if (comp == null) {
9338                    throw new IllegalArgumentException("Intent " + intent
9339                            + " must specify explicit component");
9340                }
9341                if (thumbnail.getWidth() != mThumbnailWidth
9342                        || thumbnail.getHeight() != mThumbnailHeight) {
9343                    throw new IllegalArgumentException("Bad thumbnail size: got "
9344                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9345                            + mThumbnailWidth + "x" + mThumbnailHeight);
9346                }
9347                if (intent.getSelector() != null) {
9348                    intent.setSelector(null);
9349                }
9350                if (intent.getSourceBounds() != null) {
9351                    intent.setSourceBounds(null);
9352                }
9353                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9354                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9355                        // The caller has added this as an auto-remove task...  that makes no
9356                        // sense, so turn off auto-remove.
9357                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9358                    }
9359                }
9360                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9361                    mLastAddedTaskActivity = null;
9362                }
9363                ActivityInfo ainfo = mLastAddedTaskActivity;
9364                if (ainfo == null) {
9365                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9366                            comp, 0, UserHandle.getUserId(callingUid));
9367                    if (ainfo.applicationInfo.uid != callingUid) {
9368                        throw new SecurityException(
9369                                "Can't add task for another application: target uid="
9370                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9371                    }
9372                }
9373
9374                // Use the full screen as the context for the task thumbnail
9375                final Point displaySize = new Point();
9376                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9377                r.task.stack.getDisplaySize(displaySize);
9378                thumbnailInfo.taskWidth = displaySize.x;
9379                thumbnailInfo.taskHeight = displaySize.y;
9380                thumbnailInfo.screenOrientation = mConfiguration.orientation;
9381
9382                TaskRecord task = new TaskRecord(this,
9383                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9384                        ainfo, intent, description, thumbnailInfo);
9385
9386                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9387                if (trimIdx >= 0) {
9388                    // If this would have caused a trim, then we'll abort because that
9389                    // means it would be added at the end of the list but then just removed.
9390                    return INVALID_TASK_ID;
9391                }
9392
9393                final int N = mRecentTasks.size();
9394                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9395                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9396                    tr.removedFromRecents();
9397                }
9398
9399                task.inRecents = true;
9400                mRecentTasks.add(task);
9401                r.task.stack.addTask(task, false, "addAppTask");
9402
9403                task.setLastThumbnailLocked(thumbnail);
9404                task.freeLastThumbnail();
9405
9406                return task.taskId;
9407            }
9408        } finally {
9409            Binder.restoreCallingIdentity(callingIdent);
9410        }
9411    }
9412
9413    @Override
9414    public Point getAppTaskThumbnailSize() {
9415        synchronized (this) {
9416            return new Point(mThumbnailWidth,  mThumbnailHeight);
9417        }
9418    }
9419
9420    @Override
9421    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9422        synchronized (this) {
9423            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9424            if (r != null) {
9425                r.setTaskDescription(td);
9426                r.task.updateTaskDescription();
9427            }
9428        }
9429    }
9430
9431    @Override
9432    public void setTaskResizeable(int taskId, int resizeableMode) {
9433        synchronized (this) {
9434            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9435                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9436            if (task == null) {
9437                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9438                return;
9439            }
9440            if (task.mResizeMode != resizeableMode) {
9441                task.mResizeMode = resizeableMode;
9442                mWindowManager.setTaskResizeable(taskId, resizeableMode);
9443                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9444                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9445            }
9446        }
9447    }
9448
9449    @Override
9450    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9451        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9452        long ident = Binder.clearCallingIdentity();
9453        try {
9454            synchronized (this) {
9455                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9456                if (task == null) {
9457                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9458                    return;
9459                }
9460                int stackId = task.stack.mStackId;
9461                // We allow the task to scroll instead of resizing if this is a non-resizeable task
9462                // in crop windows resize mode or if the task size is affected by the docked stack
9463                // changing size. No need to update configuration.
9464                if (bounds != null && task.inCropWindowsResizeMode()
9465                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
9466                    mWindowManager.scrollTask(task.taskId, bounds);
9467                    return;
9468                }
9469
9470                // Place the task in the right stack if it isn't there already based on
9471                // the requested bounds.
9472                // The stack transition logic is:
9473                // - a null bounds on a freeform task moves that task to fullscreen
9474                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9475                //   that task to freeform
9476                // - otherwise the task is not moved
9477                if (!StackId.isTaskResizeAllowed(stackId)) {
9478                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9479                }
9480                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9481                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9482                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9483                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9484                }
9485                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9486                if (stackId != task.stack.mStackId) {
9487                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9488                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9489                    preserveWindow = false;
9490                }
9491
9492                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9493                        false /* deferResume */);
9494            }
9495        } finally {
9496            Binder.restoreCallingIdentity(ident);
9497        }
9498    }
9499
9500    @Override
9501    public Rect getTaskBounds(int taskId) {
9502        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9503        long ident = Binder.clearCallingIdentity();
9504        Rect rect = new Rect();
9505        try {
9506            synchronized (this) {
9507                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9508                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9509                if (task == null) {
9510                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9511                    return rect;
9512                }
9513                if (task.stack != null) {
9514                    // Return the bounds from window manager since it will be adjusted for various
9515                    // things like the presense of a docked stack for tasks that aren't resizeable.
9516                    mWindowManager.getTaskBounds(task.taskId, rect);
9517                } else {
9518                    // Task isn't in window manager yet since it isn't associated with a stack.
9519                    // Return the persist value from activity manager
9520                    if (task.mBounds != null) {
9521                        rect.set(task.mBounds);
9522                    } else if (task.mLastNonFullscreenBounds != null) {
9523                        rect.set(task.mLastNonFullscreenBounds);
9524                    }
9525                }
9526            }
9527        } finally {
9528            Binder.restoreCallingIdentity(ident);
9529        }
9530        return rect;
9531    }
9532
9533    @Override
9534    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9535        if (userId != UserHandle.getCallingUserId()) {
9536            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9537                    "getTaskDescriptionIcon");
9538        }
9539        final File passedIconFile = new File(filePath);
9540        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9541                passedIconFile.getName());
9542        if (!legitIconFile.getPath().equals(filePath)
9543                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9544            throw new IllegalArgumentException("Bad file path: " + filePath
9545                    + " passed for userId " + userId);
9546        }
9547        return mRecentTasks.getTaskDescriptionIcon(filePath);
9548    }
9549
9550    @Override
9551    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9552            throws RemoteException {
9553        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9554                opts.getCustomInPlaceResId() == 0) {
9555            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9556                    "with valid animation");
9557        }
9558        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9559        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9560                opts.getCustomInPlaceResId());
9561        mWindowManager.executeAppTransition();
9562    }
9563
9564    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9565            boolean removeFromRecents) {
9566        if (removeFromRecents) {
9567            mRecentTasks.remove(tr);
9568            tr.removedFromRecents();
9569        }
9570        ComponentName component = tr.getBaseIntent().getComponent();
9571        if (component == null) {
9572            Slog.w(TAG, "No component for base intent of task: " + tr);
9573            return;
9574        }
9575
9576        // Find any running services associated with this app and stop if needed.
9577        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9578
9579        if (!killProcess) {
9580            return;
9581        }
9582
9583        // Determine if the process(es) for this task should be killed.
9584        final String pkg = component.getPackageName();
9585        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9586        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9587        for (int i = 0; i < pmap.size(); i++) {
9588
9589            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9590            for (int j = 0; j < uids.size(); j++) {
9591                ProcessRecord proc = uids.valueAt(j);
9592                if (proc.userId != tr.userId) {
9593                    // Don't kill process for a different user.
9594                    continue;
9595                }
9596                if (proc == mHomeProcess) {
9597                    // Don't kill the home process along with tasks from the same package.
9598                    continue;
9599                }
9600                if (!proc.pkgList.containsKey(pkg)) {
9601                    // Don't kill process that is not associated with this task.
9602                    continue;
9603                }
9604
9605                for (int k = 0; k < proc.activities.size(); k++) {
9606                    TaskRecord otherTask = proc.activities.get(k).task;
9607                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9608                        // Don't kill process(es) that has an activity in a different task that is
9609                        // also in recents.
9610                        return;
9611                    }
9612                }
9613
9614                if (proc.foregroundServices) {
9615                    // Don't kill process(es) with foreground service.
9616                    return;
9617                }
9618
9619                // Add process to kill list.
9620                procsToKill.add(proc);
9621            }
9622        }
9623
9624        // Kill the running processes.
9625        for (int i = 0; i < procsToKill.size(); i++) {
9626            ProcessRecord pr = procsToKill.get(i);
9627            if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9628                    && pr.curReceivers.isEmpty()) {
9629                pr.kill("remove task", true);
9630            } else {
9631                // We delay killing processes that are not in the background or running a receiver.
9632                pr.waitingToKill = "remove task";
9633            }
9634        }
9635    }
9636
9637    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9638        // Remove all tasks with activities in the specified package from the list of recent tasks
9639        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9640            TaskRecord tr = mRecentTasks.get(i);
9641            if (tr.userId != userId) continue;
9642
9643            ComponentName cn = tr.intent.getComponent();
9644            if (cn != null && cn.getPackageName().equals(packageName)) {
9645                // If the package name matches, remove the task.
9646                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9647            }
9648        }
9649    }
9650
9651    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9652            int userId) {
9653
9654        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9655            TaskRecord tr = mRecentTasks.get(i);
9656            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9657                continue;
9658            }
9659
9660            ComponentName cn = tr.intent.getComponent();
9661            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9662                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9663            if (sameComponent) {
9664                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9665            }
9666        }
9667    }
9668
9669    /**
9670     * Removes the task with the specified task id.
9671     *
9672     * @param taskId Identifier of the task to be removed.
9673     * @param killProcess Kill any process associated with the task if possible.
9674     * @param removeFromRecents Whether to also remove the task from recents.
9675     * @return Returns true if the given task was found and removed.
9676     */
9677    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9678            boolean removeFromRecents) {
9679        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9680                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9681        if (tr != null) {
9682            tr.removeTaskActivitiesLocked();
9683            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9684            if (tr.isPersistable) {
9685                notifyTaskPersisterLocked(null, true);
9686            }
9687            return true;
9688        }
9689        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9690        return false;
9691    }
9692
9693    @Override
9694    public void removeStack(int stackId) {
9695        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9696        if (stackId == HOME_STACK_ID) {
9697            throw new IllegalArgumentException("Removing home stack is not allowed.");
9698        }
9699
9700        synchronized (this) {
9701            final long ident = Binder.clearCallingIdentity();
9702            try {
9703                final ActivityStack stack = mStackSupervisor.getStack(stackId);
9704                if (stack == null) {
9705                    return;
9706                }
9707                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9708                for (int i = tasks.size() - 1; i >= 0; i--) {
9709                    removeTaskByIdLocked(
9710                            tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9711                }
9712            } finally {
9713                Binder.restoreCallingIdentity(ident);
9714            }
9715        }
9716    }
9717
9718    @Override
9719    public boolean removeTask(int taskId) {
9720        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9721        synchronized (this) {
9722            final long ident = Binder.clearCallingIdentity();
9723            try {
9724                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9725            } finally {
9726                Binder.restoreCallingIdentity(ident);
9727            }
9728        }
9729    }
9730
9731    /**
9732     * TODO: Add mController hook
9733     */
9734    @Override
9735    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9736        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9737
9738        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9739        synchronized(this) {
9740            moveTaskToFrontLocked(taskId, flags, bOptions);
9741        }
9742    }
9743
9744    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9745        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9746
9747        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9748                Binder.getCallingUid(), -1, -1, "Task to front")) {
9749            ActivityOptions.abort(options);
9750            return;
9751        }
9752        final long origId = Binder.clearCallingIdentity();
9753        try {
9754            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9755            if (task == null) {
9756                Slog.d(TAG, "Could not find task for id: "+ taskId);
9757                return;
9758            }
9759            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9760                mStackSupervisor.showLockTaskToast();
9761                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9762                return;
9763            }
9764            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9765            if (prev != null && prev.isRecentsActivity()) {
9766                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9767            }
9768            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9769                    false /* forceNonResizable */);
9770        } finally {
9771            Binder.restoreCallingIdentity(origId);
9772        }
9773        ActivityOptions.abort(options);
9774    }
9775
9776    /**
9777     * Moves an activity, and all of the other activities within the same task, to the bottom
9778     * of the history stack.  The activity's order within the task is unchanged.
9779     *
9780     * @param token A reference to the activity we wish to move
9781     * @param nonRoot If false then this only works if the activity is the root
9782     *                of a task; if true it will work for any activity in a task.
9783     * @return Returns true if the move completed, false if not.
9784     */
9785    @Override
9786    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9787        enforceNotIsolatedCaller("moveActivityTaskToBack");
9788        synchronized(this) {
9789            final long origId = Binder.clearCallingIdentity();
9790            try {
9791                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9792                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9793                if (task != null) {
9794                    if (mStackSupervisor.isLockedTask(task)) {
9795                        mStackSupervisor.showLockTaskToast();
9796                        return false;
9797                    }
9798                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9799                }
9800            } finally {
9801                Binder.restoreCallingIdentity(origId);
9802            }
9803        }
9804        return false;
9805    }
9806
9807    @Override
9808    public void moveTaskBackwards(int task) {
9809        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9810                "moveTaskBackwards()");
9811
9812        synchronized(this) {
9813            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9814                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9815                return;
9816            }
9817            final long origId = Binder.clearCallingIdentity();
9818            moveTaskBackwardsLocked(task);
9819            Binder.restoreCallingIdentity(origId);
9820        }
9821    }
9822
9823    private final void moveTaskBackwardsLocked(int task) {
9824        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9825    }
9826
9827    @Override
9828    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9829            IActivityContainerCallback callback) throws RemoteException {
9830        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9831        synchronized (this) {
9832            if (parentActivityToken == null) {
9833                throw new IllegalArgumentException("parent token must not be null");
9834            }
9835            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9836            if (r == null) {
9837                return null;
9838            }
9839            if (callback == null) {
9840                throw new IllegalArgumentException("callback must not be null");
9841            }
9842            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9843        }
9844    }
9845
9846    @Override
9847    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9848        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9849        synchronized (this) {
9850            mStackSupervisor.deleteActivityContainer(container);
9851        }
9852    }
9853
9854    @Override
9855    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9856        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9857        synchronized (this) {
9858            final int stackId = mStackSupervisor.getNextStackId();
9859            final ActivityStack stack =
9860                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9861            if (stack == null) {
9862                return null;
9863            }
9864            return stack.mActivityContainer;
9865        }
9866    }
9867
9868    @Override
9869    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9870        synchronized (this) {
9871            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9872            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9873                return stack.mActivityContainer.getDisplayId();
9874            }
9875            return Display.DEFAULT_DISPLAY;
9876        }
9877    }
9878
9879    @Override
9880    public int getActivityStackId(IBinder token) throws RemoteException {
9881        synchronized (this) {
9882            ActivityStack stack = ActivityRecord.getStackLocked(token);
9883            if (stack == null) {
9884                return INVALID_STACK_ID;
9885            }
9886            return stack.mStackId;
9887        }
9888    }
9889
9890    @Override
9891    public void exitFreeformMode(IBinder token) throws RemoteException {
9892        synchronized (this) {
9893            long ident = Binder.clearCallingIdentity();
9894            try {
9895                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9896                if (r == null) {
9897                    throw new IllegalArgumentException(
9898                            "exitFreeformMode: No activity record matching token=" + token);
9899                }
9900                final ActivityStack stack = r.getStackLocked(token);
9901                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9902                    throw new IllegalStateException(
9903                            "exitFreeformMode: You can only go fullscreen from freeform.");
9904                }
9905                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9906                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9907                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9908            } finally {
9909                Binder.restoreCallingIdentity(ident);
9910            }
9911        }
9912    }
9913
9914    @Override
9915    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9916        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9917        if (stackId == HOME_STACK_ID) {
9918            throw new IllegalArgumentException(
9919                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9920        }
9921        synchronized (this) {
9922            long ident = Binder.clearCallingIdentity();
9923            try {
9924                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9925                        + " to stackId=" + stackId + " toTop=" + toTop);
9926                if (stackId == DOCKED_STACK_ID) {
9927                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9928                            null /* initialBounds */);
9929                }
9930                boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9931                        !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9932                if (result && stackId == DOCKED_STACK_ID) {
9933                    // If task moved to docked stack - show recents if needed.
9934                    mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9935                            "moveTaskToDockedStack");
9936                }
9937            } finally {
9938                Binder.restoreCallingIdentity(ident);
9939            }
9940        }
9941    }
9942
9943    @Override
9944    public void swapDockedAndFullscreenStack() throws RemoteException {
9945        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9946        synchronized (this) {
9947            long ident = Binder.clearCallingIdentity();
9948            try {
9949                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9950                        FULLSCREEN_WORKSPACE_STACK_ID);
9951                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9952                        : null;
9953                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9954                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9955                        : null;
9956                if (topTask == null || tasks == null || tasks.size() == 0) {
9957                    Slog.w(TAG,
9958                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
9959                    return;
9960                }
9961
9962                // TODO: App transition
9963                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9964
9965                // Defer the resume so resume/pausing while moving stacks is dangerous.
9966                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9967                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9968                        ANIMATE, true /* deferResume */);
9969                final int size = tasks.size();
9970                for (int i = 0; i < size; i++) {
9971                    final int id = tasks.get(i).taskId;
9972                    if (id == topTask.taskId) {
9973                        continue;
9974                    }
9975                    mStackSupervisor.moveTaskToStackLocked(id,
9976                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9977                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9978                }
9979
9980                // Because we deferred the resume, to avoid conflicts with stack switches while
9981                // resuming, we need to do it after all the tasks are moved.
9982                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9983                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9984
9985                mWindowManager.executeAppTransition();
9986            } finally {
9987                Binder.restoreCallingIdentity(ident);
9988            }
9989        }
9990    }
9991
9992    /**
9993     * Moves the input task to the docked stack.
9994     *
9995     * @param taskId Id of task to move.
9996     * @param createMode The mode the docked stack should be created in if it doesn't exist
9997     *                   already. See
9998     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9999     *                   and
10000     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
10001     * @param toTop If the task and stack should be moved to the top.
10002     * @param animate Whether we should play an animation for the moving the task
10003     * @param initialBounds If the docked stack gets created, it will use these bounds for the
10004     *                      docked stack. Pass {@code null} to use default bounds.
10005     */
10006    @Override
10007    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
10008            Rect initialBounds, boolean moveHomeStackFront) {
10009        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
10010        synchronized (this) {
10011            long ident = Binder.clearCallingIdentity();
10012            try {
10013                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
10014                        + " to createMode=" + createMode + " toTop=" + toTop);
10015                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
10016                final boolean moved = mStackSupervisor.moveTaskToStackLocked(
10017                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
10018                        animate, DEFER_RESUME);
10019                if (moved) {
10020                    if (moveHomeStackFront) {
10021                        mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
10022                    }
10023                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10024                }
10025                return moved;
10026            } finally {
10027                Binder.restoreCallingIdentity(ident);
10028            }
10029        }
10030    }
10031
10032    /**
10033     * Moves the top activity in the input stackId to the pinned stack.
10034     *
10035     * @param stackId Id of stack to move the top activity to pinned stack.
10036     * @param bounds Bounds to use for pinned stack.
10037     *
10038     * @return True if the top activity of the input stack was successfully moved to the pinned
10039     *          stack.
10040     */
10041    @Override
10042    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
10043        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
10044        synchronized (this) {
10045            if (!mSupportsPictureInPicture) {
10046                throw new IllegalStateException("moveTopActivityToPinnedStack:"
10047                        + "Device doesn't support picture-in-pciture mode");
10048            }
10049
10050            long ident = Binder.clearCallingIdentity();
10051            try {
10052                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
10053            } finally {
10054                Binder.restoreCallingIdentity(ident);
10055            }
10056        }
10057    }
10058
10059    @Override
10060    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
10061            boolean preserveWindows, boolean animate, int animationDuration) {
10062        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
10063        long ident = Binder.clearCallingIdentity();
10064        try {
10065            synchronized (this) {
10066                if (animate) {
10067                    if (stackId == PINNED_STACK_ID) {
10068                        mWindowManager.animateResizePinnedStack(bounds, animationDuration);
10069                    } else {
10070                        throw new IllegalArgumentException("Stack: " + stackId
10071                                + " doesn't support animated resize.");
10072                    }
10073                } else {
10074                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
10075                            null /* tempTaskInsetBounds */, preserveWindows,
10076                            allowResizeInDockedMode, !DEFER_RESUME);
10077                }
10078            }
10079        } finally {
10080            Binder.restoreCallingIdentity(ident);
10081        }
10082    }
10083
10084    @Override
10085    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10086            Rect tempDockedTaskInsetBounds,
10087            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10088        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10089                "resizeDockedStack()");
10090        long ident = Binder.clearCallingIdentity();
10091        try {
10092            synchronized (this) {
10093                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10094                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10095                        PRESERVE_WINDOWS);
10096            }
10097        } finally {
10098            Binder.restoreCallingIdentity(ident);
10099        }
10100    }
10101
10102    @Override
10103    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10104        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10105                "resizePinnedStack()");
10106        final long ident = Binder.clearCallingIdentity();
10107        try {
10108            synchronized (this) {
10109                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10110            }
10111        } finally {
10112            Binder.restoreCallingIdentity(ident);
10113        }
10114    }
10115
10116    @Override
10117    public void positionTaskInStack(int taskId, int stackId, int position) {
10118        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10119        if (stackId == HOME_STACK_ID) {
10120            throw new IllegalArgumentException(
10121                    "positionTaskInStack: Attempt to change the position of task "
10122                    + taskId + " in/to home stack");
10123        }
10124        synchronized (this) {
10125            long ident = Binder.clearCallingIdentity();
10126            try {
10127                if (DEBUG_STACK) Slog.d(TAG_STACK,
10128                        "positionTaskInStack: positioning task=" + taskId
10129                        + " in stackId=" + stackId + " at position=" + position);
10130                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
10131            } finally {
10132                Binder.restoreCallingIdentity(ident);
10133            }
10134        }
10135    }
10136
10137    @Override
10138    public List<StackInfo> getAllStackInfos() {
10139        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10140        long ident = Binder.clearCallingIdentity();
10141        try {
10142            synchronized (this) {
10143                return mStackSupervisor.getAllStackInfosLocked();
10144            }
10145        } finally {
10146            Binder.restoreCallingIdentity(ident);
10147        }
10148    }
10149
10150    @Override
10151    public StackInfo getStackInfo(int stackId) {
10152        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10153        long ident = Binder.clearCallingIdentity();
10154        try {
10155            synchronized (this) {
10156                return mStackSupervisor.getStackInfoLocked(stackId);
10157            }
10158        } finally {
10159            Binder.restoreCallingIdentity(ident);
10160        }
10161    }
10162
10163    @Override
10164    public boolean isInHomeStack(int taskId) {
10165        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10166        long ident = Binder.clearCallingIdentity();
10167        try {
10168            synchronized (this) {
10169                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10170                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
10171                return tr != null && tr.stack != null && tr.stack.isHomeStack();
10172            }
10173        } finally {
10174            Binder.restoreCallingIdentity(ident);
10175        }
10176    }
10177
10178    @Override
10179    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10180        synchronized(this) {
10181            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10182        }
10183    }
10184
10185    @Override
10186    public void updateDeviceOwner(String packageName) {
10187        final int callingUid = Binder.getCallingUid();
10188        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10189            throw new SecurityException("updateDeviceOwner called from non-system process");
10190        }
10191        synchronized (this) {
10192            mDeviceOwnerName = packageName;
10193        }
10194    }
10195
10196    @Override
10197    public void updateLockTaskPackages(int userId, String[] packages) {
10198        final int callingUid = Binder.getCallingUid();
10199        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10200            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10201                    "updateLockTaskPackages()");
10202        }
10203        synchronized (this) {
10204            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10205                    Arrays.toString(packages));
10206            mLockTaskPackages.put(userId, packages);
10207            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10208        }
10209    }
10210
10211
10212    void startLockTaskModeLocked(TaskRecord task) {
10213        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10214        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10215            return;
10216        }
10217
10218        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10219        // is initiated by system after the pinning request was shown and locked mode is initiated
10220        // by an authorized app directly
10221        final int callingUid = Binder.getCallingUid();
10222        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10223        long ident = Binder.clearCallingIdentity();
10224        try {
10225            if (!isSystemInitiated) {
10226                task.mLockTaskUid = callingUid;
10227                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10228                    // startLockTask() called by app and task mode is lockTaskModeDefault.
10229                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10230                    StatusBarManagerInternal statusBarManager =
10231                            LocalServices.getService(StatusBarManagerInternal.class);
10232                    if (statusBarManager != null) {
10233                        statusBarManager.showScreenPinningRequest(task.taskId);
10234                    }
10235                    return;
10236                }
10237
10238                final ActivityStack stack = mStackSupervisor.getFocusedStack();
10239                if (stack == null || task != stack.topTask()) {
10240                    throw new IllegalArgumentException("Invalid task, not in foreground");
10241                }
10242            }
10243            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10244                    "Locking fully");
10245            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10246                    ActivityManager.LOCK_TASK_MODE_PINNED :
10247                    ActivityManager.LOCK_TASK_MODE_LOCKED,
10248                    "startLockTask", true);
10249        } finally {
10250            Binder.restoreCallingIdentity(ident);
10251        }
10252    }
10253
10254    @Override
10255    public void startLockTaskMode(int taskId) {
10256        synchronized (this) {
10257            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10258            if (task != null) {
10259                startLockTaskModeLocked(task);
10260            }
10261        }
10262    }
10263
10264    @Override
10265    public void startLockTaskMode(IBinder token) {
10266        synchronized (this) {
10267            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10268            if (r == null) {
10269                return;
10270            }
10271            final TaskRecord task = r.task;
10272            if (task != null) {
10273                startLockTaskModeLocked(task);
10274            }
10275        }
10276    }
10277
10278    @Override
10279    public void startSystemLockTaskMode(int taskId) throws RemoteException {
10280        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10281        // This makes inner call to look as if it was initiated by system.
10282        long ident = Binder.clearCallingIdentity();
10283        try {
10284            synchronized (this) {
10285                startLockTaskMode(taskId);
10286            }
10287        } finally {
10288            Binder.restoreCallingIdentity(ident);
10289        }
10290    }
10291
10292    @Override
10293    public void stopLockTaskMode() {
10294        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10295        if (lockTask == null) {
10296            // Our work here is done.
10297            return;
10298        }
10299
10300        final int callingUid = Binder.getCallingUid();
10301        final int lockTaskUid = lockTask.mLockTaskUid;
10302        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10303        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10304            // Done.
10305            return;
10306        } else {
10307            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10308            // It is possible lockTaskMode was started by the system process because
10309            // android:lockTaskMode is set to a locking value in the application manifest
10310            // instead of the app calling startLockTaskMode. In this case
10311            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10312            // {@link TaskRecord.effectiveUid} instead. Also caller with
10313            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10314            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10315                    && callingUid != lockTaskUid
10316                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10317                throw new SecurityException("Invalid uid, expected " + lockTaskUid
10318                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10319            }
10320        }
10321        long ident = Binder.clearCallingIdentity();
10322        try {
10323            Log.d(TAG, "stopLockTaskMode");
10324            // Stop lock task
10325            synchronized (this) {
10326                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10327                        "stopLockTask", true);
10328            }
10329            TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10330            if (tm != null) {
10331                tm.showInCallScreen(false);
10332            }
10333        } finally {
10334            Binder.restoreCallingIdentity(ident);
10335        }
10336    }
10337
10338    /**
10339     * This API should be called by SystemUI only when user perform certain action to dismiss
10340     * lock task mode. We should only dismiss pinned lock task mode in this case.
10341     */
10342    @Override
10343    public void stopSystemLockTaskMode() throws RemoteException {
10344        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10345            stopLockTaskMode();
10346        } else {
10347            mStackSupervisor.showLockTaskToast();
10348        }
10349    }
10350
10351    @Override
10352    public boolean isInLockTaskMode() {
10353        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10354    }
10355
10356    @Override
10357    public int getLockTaskModeState() {
10358        synchronized (this) {
10359            return mStackSupervisor.getLockTaskModeState();
10360        }
10361    }
10362
10363    @Override
10364    public void showLockTaskEscapeMessage(IBinder token) {
10365        synchronized (this) {
10366            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10367            if (r == null) {
10368                return;
10369            }
10370            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10371        }
10372    }
10373
10374    // =========================================================
10375    // CONTENT PROVIDERS
10376    // =========================================================
10377
10378    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10379        List<ProviderInfo> providers = null;
10380        try {
10381            providers = AppGlobals.getPackageManager()
10382                    .queryContentProviders(app.processName, app.uid,
10383                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10384                                    | MATCH_DEBUG_TRIAGED_MISSING)
10385                    .getList();
10386        } catch (RemoteException ex) {
10387        }
10388        if (DEBUG_MU) Slog.v(TAG_MU,
10389                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10390        int userId = app.userId;
10391        if (providers != null) {
10392            int N = providers.size();
10393            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10394            for (int i=0; i<N; i++) {
10395                // TODO: keep logic in sync with installEncryptionUnawareProviders
10396                ProviderInfo cpi =
10397                    (ProviderInfo)providers.get(i);
10398                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10399                        cpi.name, cpi.flags);
10400                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10401                    // This is a singleton provider, but a user besides the
10402                    // default user is asking to initialize a process it runs
10403                    // in...  well, no, it doesn't actually run in this process,
10404                    // it runs in the process of the default user.  Get rid of it.
10405                    providers.remove(i);
10406                    N--;
10407                    i--;
10408                    continue;
10409                }
10410
10411                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10412                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10413                if (cpr == null) {
10414                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10415                    mProviderMap.putProviderByClass(comp, cpr);
10416                }
10417                if (DEBUG_MU) Slog.v(TAG_MU,
10418                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10419                app.pubProviders.put(cpi.name, cpr);
10420                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10421                    // Don't add this if it is a platform component that is marked
10422                    // to run in multiple processes, because this is actually
10423                    // part of the framework so doesn't make sense to track as a
10424                    // separate apk in the process.
10425                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10426                            mProcessStats);
10427                }
10428                notifyPackageUse(cpi.applicationInfo.packageName,
10429                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10430            }
10431        }
10432        return providers;
10433    }
10434
10435    /**
10436     * Check if {@link ProcessRecord} has a possible chance at accessing the
10437     * given {@link ProviderInfo}. Final permission checking is always done
10438     * in {@link ContentProvider}.
10439     */
10440    private final String checkContentProviderPermissionLocked(
10441            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10442        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10443        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10444        boolean checkedGrants = false;
10445        if (checkUser) {
10446            // Looking for cross-user grants before enforcing the typical cross-users permissions
10447            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10448            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10449                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10450                    return null;
10451                }
10452                checkedGrants = true;
10453            }
10454            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10455                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10456            if (userId != tmpTargetUserId) {
10457                // When we actually went to determine the final targer user ID, this ended
10458                // up different than our initial check for the authority.  This is because
10459                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10460                // SELF.  So we need to re-check the grants again.
10461                checkedGrants = false;
10462            }
10463        }
10464        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10465                cpi.applicationInfo.uid, cpi.exported)
10466                == PackageManager.PERMISSION_GRANTED) {
10467            return null;
10468        }
10469        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10470                cpi.applicationInfo.uid, cpi.exported)
10471                == PackageManager.PERMISSION_GRANTED) {
10472            return null;
10473        }
10474
10475        PathPermission[] pps = cpi.pathPermissions;
10476        if (pps != null) {
10477            int i = pps.length;
10478            while (i > 0) {
10479                i--;
10480                PathPermission pp = pps[i];
10481                String pprperm = pp.getReadPermission();
10482                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10483                        cpi.applicationInfo.uid, cpi.exported)
10484                        == PackageManager.PERMISSION_GRANTED) {
10485                    return null;
10486                }
10487                String ppwperm = pp.getWritePermission();
10488                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10489                        cpi.applicationInfo.uid, cpi.exported)
10490                        == PackageManager.PERMISSION_GRANTED) {
10491                    return null;
10492                }
10493            }
10494        }
10495        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10496            return null;
10497        }
10498
10499        String msg;
10500        if (!cpi.exported) {
10501            msg = "Permission Denial: opening provider " + cpi.name
10502                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10503                    + ", uid=" + callingUid + ") that is not exported from uid "
10504                    + cpi.applicationInfo.uid;
10505        } else {
10506            msg = "Permission Denial: opening provider " + cpi.name
10507                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10508                    + ", uid=" + callingUid + ") requires "
10509                    + cpi.readPermission + " or " + cpi.writePermission;
10510        }
10511        Slog.w(TAG, msg);
10512        return msg;
10513    }
10514
10515    /**
10516     * Returns if the ContentProvider has granted a uri to callingUid
10517     */
10518    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10519        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10520        if (perms != null) {
10521            for (int i=perms.size()-1; i>=0; i--) {
10522                GrantUri grantUri = perms.keyAt(i);
10523                if (grantUri.sourceUserId == userId || !checkUser) {
10524                    if (matchesProvider(grantUri.uri, cpi)) {
10525                        return true;
10526                    }
10527                }
10528            }
10529        }
10530        return false;
10531    }
10532
10533    /**
10534     * Returns true if the uri authority is one of the authorities specified in the provider.
10535     */
10536    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10537        String uriAuth = uri.getAuthority();
10538        String cpiAuth = cpi.authority;
10539        if (cpiAuth.indexOf(';') == -1) {
10540            return cpiAuth.equals(uriAuth);
10541        }
10542        String[] cpiAuths = cpiAuth.split(";");
10543        int length = cpiAuths.length;
10544        for (int i = 0; i < length; i++) {
10545            if (cpiAuths[i].equals(uriAuth)) return true;
10546        }
10547        return false;
10548    }
10549
10550    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10551            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10552        if (r != null) {
10553            for (int i=0; i<r.conProviders.size(); i++) {
10554                ContentProviderConnection conn = r.conProviders.get(i);
10555                if (conn.provider == cpr) {
10556                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10557                            "Adding provider requested by "
10558                            + r.processName + " from process "
10559                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10560                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10561                    if (stable) {
10562                        conn.stableCount++;
10563                        conn.numStableIncs++;
10564                    } else {
10565                        conn.unstableCount++;
10566                        conn.numUnstableIncs++;
10567                    }
10568                    return conn;
10569                }
10570            }
10571            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10572            if (stable) {
10573                conn.stableCount = 1;
10574                conn.numStableIncs = 1;
10575            } else {
10576                conn.unstableCount = 1;
10577                conn.numUnstableIncs = 1;
10578            }
10579            cpr.connections.add(conn);
10580            r.conProviders.add(conn);
10581            startAssociationLocked(r.uid, r.processName, r.curProcState,
10582                    cpr.uid, cpr.name, cpr.info.processName);
10583            return conn;
10584        }
10585        cpr.addExternalProcessHandleLocked(externalProcessToken);
10586        return null;
10587    }
10588
10589    boolean decProviderCountLocked(ContentProviderConnection conn,
10590            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10591        if (conn != null) {
10592            cpr = conn.provider;
10593            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10594                    "Removing provider requested by "
10595                    + conn.client.processName + " from process "
10596                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10597                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10598            if (stable) {
10599                conn.stableCount--;
10600            } else {
10601                conn.unstableCount--;
10602            }
10603            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10604                cpr.connections.remove(conn);
10605                conn.client.conProviders.remove(conn);
10606                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10607                    // The client is more important than last activity -- note the time this
10608                    // is happening, so we keep the old provider process around a bit as last
10609                    // activity to avoid thrashing it.
10610                    if (cpr.proc != null) {
10611                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10612                    }
10613                }
10614                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10615                return true;
10616            }
10617            return false;
10618        }
10619        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10620        return false;
10621    }
10622
10623    private void checkTime(long startTime, String where) {
10624        long now = SystemClock.uptimeMillis();
10625        if ((now-startTime) > 50) {
10626            // If we are taking more than 50ms, log about it.
10627            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10628        }
10629    }
10630
10631    private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
10632            PROC_SPACE_TERM,
10633            PROC_SPACE_TERM|PROC_PARENS,
10634            PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
10635    };
10636
10637    private final long[] mProcessStateStatsLongs = new long[1];
10638
10639    boolean isProcessAliveLocked(ProcessRecord proc) {
10640        if (proc.procStatFile == null) {
10641            proc.procStatFile = "/proc/" + proc.pid + "/stat";
10642        }
10643        mProcessStateStatsLongs[0] = 0;
10644        if (!Process.readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
10645                mProcessStateStatsLongs, null)) {
10646            if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
10647            return false;
10648        }
10649        final long state = mProcessStateStatsLongs[0];
10650        if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
10651                + (char)state);
10652        return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
10653    }
10654
10655    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10656            String name, IBinder token, boolean stable, int userId) {
10657        ContentProviderRecord cpr;
10658        ContentProviderConnection conn = null;
10659        ProviderInfo cpi = null;
10660
10661        synchronized(this) {
10662            long startTime = SystemClock.uptimeMillis();
10663
10664            ProcessRecord r = null;
10665            if (caller != null) {
10666                r = getRecordForAppLocked(caller);
10667                if (r == null) {
10668                    throw new SecurityException(
10669                            "Unable to find app for caller " + caller
10670                          + " (pid=" + Binder.getCallingPid()
10671                          + ") when getting content provider " + name);
10672                }
10673            }
10674
10675            boolean checkCrossUser = true;
10676
10677            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10678
10679            // First check if this content provider has been published...
10680            cpr = mProviderMap.getProviderByName(name, userId);
10681            // If that didn't work, check if it exists for user 0 and then
10682            // verify that it's a singleton provider before using it.
10683            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10684                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10685                if (cpr != null) {
10686                    cpi = cpr.info;
10687                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10688                            cpi.name, cpi.flags)
10689                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10690                        userId = UserHandle.USER_SYSTEM;
10691                        checkCrossUser = false;
10692                    } else {
10693                        cpr = null;
10694                        cpi = null;
10695                    }
10696                }
10697            }
10698
10699            boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
10700            if (providerRunning) {
10701                cpi = cpr.info;
10702                String msg;
10703                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10704                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10705                        != null) {
10706                    throw new SecurityException(msg);
10707                }
10708                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10709
10710                if (r != null && cpr.canRunHere(r)) {
10711                    // This provider has been published or is in the process
10712                    // of being published...  but it is also allowed to run
10713                    // in the caller's process, so don't make a connection
10714                    // and just let the caller instantiate its own instance.
10715                    ContentProviderHolder holder = cpr.newHolder(null);
10716                    // don't give caller the provider object, it needs
10717                    // to make its own.
10718                    holder.provider = null;
10719                    return holder;
10720                }
10721
10722                final long origId = Binder.clearCallingIdentity();
10723
10724                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10725
10726                // In this case the provider instance already exists, so we can
10727                // return it right away.
10728                conn = incProviderCountLocked(r, cpr, token, stable);
10729                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10730                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10731                        // If this is a perceptible app accessing the provider,
10732                        // make sure to count it as being accessed and thus
10733                        // back up on the LRU list.  This is good because
10734                        // content providers are often expensive to start.
10735                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10736                        updateLruProcessLocked(cpr.proc, false, null);
10737                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10738                    }
10739                }
10740
10741                checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10742                final int verifiedAdj = cpr.proc.verifiedAdj;
10743                boolean success = updateOomAdjLocked(cpr.proc);
10744                // XXX things have changed so updateOomAdjLocked doesn't actually tell us
10745                // if the process has been successfully adjusted.  So to reduce races with
10746                // it, we will check whether the process still exists.  Note that this doesn't
10747                // completely get rid of races with LMK killing the process, but should make
10748                // them much smaller.
10749                if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
10750                    success = false;
10751                }
10752                maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10753                checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10754                if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10755                // NOTE: there is still a race here where a signal could be
10756                // pending on the process even though we managed to update its
10757                // adj level.  Not sure what to do about this, but at least
10758                // the race is now smaller.
10759                if (!success) {
10760                    // Uh oh...  it looks like the provider's process
10761                    // has been killed on us.  We need to wait for a new
10762                    // process to be started, and make sure its death
10763                    // doesn't kill our process.
10764                    Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10765                            + " is crashing; detaching " + r);
10766                    boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10767                    checkTime(startTime, "getContentProviderImpl: before appDied");
10768                    appDiedLocked(cpr.proc);
10769                    checkTime(startTime, "getContentProviderImpl: after appDied");
10770                    if (!lastRef) {
10771                        // This wasn't the last ref our process had on
10772                        // the provider...  we have now been killed, bail.
10773                        return null;
10774                    }
10775                    providerRunning = false;
10776                    conn = null;
10777                } else {
10778                    cpr.proc.verifiedAdj = cpr.proc.setAdj;
10779                }
10780
10781                Binder.restoreCallingIdentity(origId);
10782            }
10783
10784            if (!providerRunning) {
10785                try {
10786                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10787                    cpi = AppGlobals.getPackageManager().
10788                        resolveContentProvider(name,
10789                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10790                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10791                } catch (RemoteException ex) {
10792                }
10793                if (cpi == null) {
10794                    return null;
10795                }
10796                // If the provider is a singleton AND
10797                // (it's a call within the same user || the provider is a
10798                // privileged app)
10799                // Then allow connecting to the singleton provider
10800                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10801                        cpi.name, cpi.flags)
10802                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10803                if (singleton) {
10804                    userId = UserHandle.USER_SYSTEM;
10805                }
10806                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10807                checkTime(startTime, "getContentProviderImpl: got app info for user");
10808
10809                String msg;
10810                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10811                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10812                        != null) {
10813                    throw new SecurityException(msg);
10814                }
10815                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10816
10817                if (!mProcessesReady
10818                        && !cpi.processName.equals("system")) {
10819                    // If this content provider does not run in the system
10820                    // process, and the system is not yet ready to run other
10821                    // processes, then fail fast instead of hanging.
10822                    throw new IllegalArgumentException(
10823                            "Attempt to launch content provider before system ready");
10824                }
10825
10826                // Make sure that the user who owns this provider is running.  If not,
10827                // we don't want to allow it to run.
10828                if (!mUserController.isUserRunningLocked(userId, 0)) {
10829                    Slog.w(TAG, "Unable to launch app "
10830                            + cpi.applicationInfo.packageName + "/"
10831                            + cpi.applicationInfo.uid + " for provider "
10832                            + name + ": user " + userId + " is stopped");
10833                    return null;
10834                }
10835
10836                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10837                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10838                cpr = mProviderMap.getProviderByClass(comp, userId);
10839                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10840                final boolean firstClass = cpr == null;
10841                if (firstClass) {
10842                    final long ident = Binder.clearCallingIdentity();
10843
10844                    // If permissions need a review before any of the app components can run,
10845                    // we return no provider and launch a review activity if the calling app
10846                    // is in the foreground.
10847                    if (mPermissionReviewRequired || Build.PERMISSIONS_REVIEW_REQUIRED) {
10848                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10849                            return null;
10850                        }
10851                    }
10852
10853                    try {
10854                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10855                        ApplicationInfo ai =
10856                            AppGlobals.getPackageManager().
10857                                getApplicationInfo(
10858                                        cpi.applicationInfo.packageName,
10859                                        STOCK_PM_FLAGS, userId);
10860                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10861                        if (ai == null) {
10862                            Slog.w(TAG, "No package info for content provider "
10863                                    + cpi.name);
10864                            return null;
10865                        }
10866                        ai = getAppInfoForUser(ai, userId);
10867                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10868                    } catch (RemoteException ex) {
10869                        // pm is in same process, this will never happen.
10870                    } finally {
10871                        Binder.restoreCallingIdentity(ident);
10872                    }
10873                }
10874
10875                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10876
10877                if (r != null && cpr.canRunHere(r)) {
10878                    // If this is a multiprocess provider, then just return its
10879                    // info and allow the caller to instantiate it.  Only do
10880                    // this if the provider is the same user as the caller's
10881                    // process, or can run as root (so can be in any process).
10882                    return cpr.newHolder(null);
10883                }
10884
10885                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10886                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10887                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10888
10889                // This is single process, and our app is now connecting to it.
10890                // See if we are already in the process of launching this
10891                // provider.
10892                final int N = mLaunchingProviders.size();
10893                int i;
10894                for (i = 0; i < N; i++) {
10895                    if (mLaunchingProviders.get(i) == cpr) {
10896                        break;
10897                    }
10898                }
10899
10900                // If the provider is not already being launched, then get it
10901                // started.
10902                if (i >= N) {
10903                    final long origId = Binder.clearCallingIdentity();
10904
10905                    try {
10906                        // Content provider is now in use, its package can't be stopped.
10907                        try {
10908                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10909                            AppGlobals.getPackageManager().setPackageStoppedState(
10910                                    cpr.appInfo.packageName, false, userId);
10911                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10912                        } catch (RemoteException e) {
10913                        } catch (IllegalArgumentException e) {
10914                            Slog.w(TAG, "Failed trying to unstop package "
10915                                    + cpr.appInfo.packageName + ": " + e);
10916                        }
10917
10918                        // Use existing process if already started
10919                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10920                        ProcessRecord proc = getProcessRecordLocked(
10921                                cpi.processName, cpr.appInfo.uid, false);
10922                        if (proc != null && proc.thread != null && !proc.killed) {
10923                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10924                                    "Installing in existing process " + proc);
10925                            if (!proc.pubProviders.containsKey(cpi.name)) {
10926                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10927                                proc.pubProviders.put(cpi.name, cpr);
10928                                try {
10929                                    proc.thread.scheduleInstallProvider(cpi);
10930                                } catch (RemoteException e) {
10931                                }
10932                            }
10933                        } else {
10934                            checkTime(startTime, "getContentProviderImpl: before start process");
10935                            proc = startProcessLocked(cpi.processName,
10936                                    cpr.appInfo, false, 0, "content provider",
10937                                    new ComponentName(cpi.applicationInfo.packageName,
10938                                            cpi.name), false, false, false);
10939                            checkTime(startTime, "getContentProviderImpl: after start process");
10940                            if (proc == null) {
10941                                Slog.w(TAG, "Unable to launch app "
10942                                        + cpi.applicationInfo.packageName + "/"
10943                                        + cpi.applicationInfo.uid + " for provider "
10944                                        + name + ": process is bad");
10945                                return null;
10946                            }
10947                        }
10948                        cpr.launchingApp = proc;
10949                        mLaunchingProviders.add(cpr);
10950                    } finally {
10951                        Binder.restoreCallingIdentity(origId);
10952                    }
10953                }
10954
10955                checkTime(startTime, "getContentProviderImpl: updating data structures");
10956
10957                // Make sure the provider is published (the same provider class
10958                // may be published under multiple names).
10959                if (firstClass) {
10960                    mProviderMap.putProviderByClass(comp, cpr);
10961                }
10962
10963                mProviderMap.putProviderByName(name, cpr);
10964                conn = incProviderCountLocked(r, cpr, token, stable);
10965                if (conn != null) {
10966                    conn.waiting = true;
10967                }
10968            }
10969            checkTime(startTime, "getContentProviderImpl: done!");
10970        }
10971
10972        // Wait for the provider to be published...
10973        synchronized (cpr) {
10974            while (cpr.provider == null) {
10975                if (cpr.launchingApp == null) {
10976                    Slog.w(TAG, "Unable to launch app "
10977                            + cpi.applicationInfo.packageName + "/"
10978                            + cpi.applicationInfo.uid + " for provider "
10979                            + name + ": launching app became null");
10980                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10981                            UserHandle.getUserId(cpi.applicationInfo.uid),
10982                            cpi.applicationInfo.packageName,
10983                            cpi.applicationInfo.uid, name);
10984                    return null;
10985                }
10986                try {
10987                    if (DEBUG_MU) Slog.v(TAG_MU,
10988                            "Waiting to start provider " + cpr
10989                            + " launchingApp=" + cpr.launchingApp);
10990                    if (conn != null) {
10991                        conn.waiting = true;
10992                    }
10993                    cpr.wait();
10994                } catch (InterruptedException ex) {
10995                } finally {
10996                    if (conn != null) {
10997                        conn.waiting = false;
10998                    }
10999                }
11000            }
11001        }
11002        return cpr != null ? cpr.newHolder(conn) : null;
11003    }
11004
11005    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
11006            ProcessRecord r, final int userId) {
11007        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
11008                cpi.packageName, userId)) {
11009
11010            final boolean callerForeground = r == null || r.setSchedGroup
11011                    != ProcessList.SCHED_GROUP_BACKGROUND;
11012
11013            // Show a permission review UI only for starting from a foreground app
11014            if (!callerForeground) {
11015                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
11016                        + cpi.packageName + " requires a permissions review");
11017                return false;
11018            }
11019
11020            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
11021            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11022                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
11023            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
11024
11025            if (DEBUG_PERMISSIONS_REVIEW) {
11026                Slog.i(TAG, "u" + userId + " Launching permission review "
11027                        + "for package " + cpi.packageName);
11028            }
11029
11030            final UserHandle userHandle = new UserHandle(userId);
11031            mHandler.post(new Runnable() {
11032                @Override
11033                public void run() {
11034                    mContext.startActivityAsUser(intent, userHandle);
11035                }
11036            });
11037
11038            return false;
11039        }
11040
11041        return true;
11042    }
11043
11044    PackageManagerInternal getPackageManagerInternalLocked() {
11045        if (mPackageManagerInt == null) {
11046            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
11047        }
11048        return mPackageManagerInt;
11049    }
11050
11051    @Override
11052    public final ContentProviderHolder getContentProvider(
11053            IApplicationThread caller, String name, int userId, boolean stable) {
11054        enforceNotIsolatedCaller("getContentProvider");
11055        if (caller == null) {
11056            String msg = "null IApplicationThread when getting content provider "
11057                    + name;
11058            Slog.w(TAG, msg);
11059            throw new SecurityException(msg);
11060        }
11061        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
11062        // with cross-user grant.
11063        return getContentProviderImpl(caller, name, null, stable, userId);
11064    }
11065
11066    public ContentProviderHolder getContentProviderExternal(
11067            String name, int userId, IBinder token) {
11068        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11069            "Do not have permission in call getContentProviderExternal()");
11070        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
11071                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
11072        return getContentProviderExternalUnchecked(name, token, userId);
11073    }
11074
11075    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
11076            IBinder token, int userId) {
11077        return getContentProviderImpl(null, name, token, true, userId);
11078    }
11079
11080    /**
11081     * Drop a content provider from a ProcessRecord's bookkeeping
11082     */
11083    public void removeContentProvider(IBinder connection, boolean stable) {
11084        enforceNotIsolatedCaller("removeContentProvider");
11085        long ident = Binder.clearCallingIdentity();
11086        try {
11087            synchronized (this) {
11088                ContentProviderConnection conn;
11089                try {
11090                    conn = (ContentProviderConnection)connection;
11091                } catch (ClassCastException e) {
11092                    String msg ="removeContentProvider: " + connection
11093                            + " not a ContentProviderConnection";
11094                    Slog.w(TAG, msg);
11095                    throw new IllegalArgumentException(msg);
11096                }
11097                if (conn == null) {
11098                    throw new NullPointerException("connection is null");
11099                }
11100                if (decProviderCountLocked(conn, null, null, stable)) {
11101                    updateOomAdjLocked();
11102                }
11103            }
11104        } finally {
11105            Binder.restoreCallingIdentity(ident);
11106        }
11107    }
11108
11109    public void removeContentProviderExternal(String name, IBinder token) {
11110        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11111            "Do not have permission in call removeContentProviderExternal()");
11112        int userId = UserHandle.getCallingUserId();
11113        long ident = Binder.clearCallingIdentity();
11114        try {
11115            removeContentProviderExternalUnchecked(name, token, userId);
11116        } finally {
11117            Binder.restoreCallingIdentity(ident);
11118        }
11119    }
11120
11121    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11122        synchronized (this) {
11123            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11124            if(cpr == null) {
11125                //remove from mProvidersByClass
11126                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11127                return;
11128            }
11129
11130            //update content provider record entry info
11131            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11132            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11133            if (localCpr.hasExternalProcessHandles()) {
11134                if (localCpr.removeExternalProcessHandleLocked(token)) {
11135                    updateOomAdjLocked();
11136                } else {
11137                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11138                            + " with no external reference for token: "
11139                            + token + ".");
11140                }
11141            } else {
11142                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11143                        + " with no external references.");
11144            }
11145        }
11146    }
11147
11148    public final void publishContentProviders(IApplicationThread caller,
11149            List<ContentProviderHolder> providers) {
11150        if (providers == null) {
11151            return;
11152        }
11153
11154        enforceNotIsolatedCaller("publishContentProviders");
11155        synchronized (this) {
11156            final ProcessRecord r = getRecordForAppLocked(caller);
11157            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11158            if (r == null) {
11159                throw new SecurityException(
11160                        "Unable to find app for caller " + caller
11161                      + " (pid=" + Binder.getCallingPid()
11162                      + ") when publishing content providers");
11163            }
11164
11165            final long origId = Binder.clearCallingIdentity();
11166
11167            final int N = providers.size();
11168            for (int i = 0; i < N; i++) {
11169                ContentProviderHolder src = providers.get(i);
11170                if (src == null || src.info == null || src.provider == null) {
11171                    continue;
11172                }
11173                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11174                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11175                if (dst != null) {
11176                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11177                    mProviderMap.putProviderByClass(comp, dst);
11178                    String names[] = dst.info.authority.split(";");
11179                    for (int j = 0; j < names.length; j++) {
11180                        mProviderMap.putProviderByName(names[j], dst);
11181                    }
11182
11183                    int launchingCount = mLaunchingProviders.size();
11184                    int j;
11185                    boolean wasInLaunchingProviders = false;
11186                    for (j = 0; j < launchingCount; j++) {
11187                        if (mLaunchingProviders.get(j) == dst) {
11188                            mLaunchingProviders.remove(j);
11189                            wasInLaunchingProviders = true;
11190                            j--;
11191                            launchingCount--;
11192                        }
11193                    }
11194                    if (wasInLaunchingProviders) {
11195                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11196                    }
11197                    synchronized (dst) {
11198                        dst.provider = src.provider;
11199                        dst.proc = r;
11200                        dst.notifyAll();
11201                    }
11202                    updateOomAdjLocked(r);
11203                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11204                            src.info.authority);
11205                }
11206            }
11207
11208            Binder.restoreCallingIdentity(origId);
11209        }
11210    }
11211
11212    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11213        ContentProviderConnection conn;
11214        try {
11215            conn = (ContentProviderConnection)connection;
11216        } catch (ClassCastException e) {
11217            String msg ="refContentProvider: " + connection
11218                    + " not a ContentProviderConnection";
11219            Slog.w(TAG, msg);
11220            throw new IllegalArgumentException(msg);
11221        }
11222        if (conn == null) {
11223            throw new NullPointerException("connection is null");
11224        }
11225
11226        synchronized (this) {
11227            if (stable > 0) {
11228                conn.numStableIncs += stable;
11229            }
11230            stable = conn.stableCount + stable;
11231            if (stable < 0) {
11232                throw new IllegalStateException("stableCount < 0: " + stable);
11233            }
11234
11235            if (unstable > 0) {
11236                conn.numUnstableIncs += unstable;
11237            }
11238            unstable = conn.unstableCount + unstable;
11239            if (unstable < 0) {
11240                throw new IllegalStateException("unstableCount < 0: " + unstable);
11241            }
11242
11243            if ((stable+unstable) <= 0) {
11244                throw new IllegalStateException("ref counts can't go to zero here: stable="
11245                        + stable + " unstable=" + unstable);
11246            }
11247            conn.stableCount = stable;
11248            conn.unstableCount = unstable;
11249            return !conn.dead;
11250        }
11251    }
11252
11253    public void unstableProviderDied(IBinder connection) {
11254        ContentProviderConnection conn;
11255        try {
11256            conn = (ContentProviderConnection)connection;
11257        } catch (ClassCastException e) {
11258            String msg ="refContentProvider: " + connection
11259                    + " not a ContentProviderConnection";
11260            Slog.w(TAG, msg);
11261            throw new IllegalArgumentException(msg);
11262        }
11263        if (conn == null) {
11264            throw new NullPointerException("connection is null");
11265        }
11266
11267        // Safely retrieve the content provider associated with the connection.
11268        IContentProvider provider;
11269        synchronized (this) {
11270            provider = conn.provider.provider;
11271        }
11272
11273        if (provider == null) {
11274            // Um, yeah, we're way ahead of you.
11275            return;
11276        }
11277
11278        // Make sure the caller is being honest with us.
11279        if (provider.asBinder().pingBinder()) {
11280            // Er, no, still looks good to us.
11281            synchronized (this) {
11282                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11283                        + " says " + conn + " died, but we don't agree");
11284                return;
11285            }
11286        }
11287
11288        // Well look at that!  It's dead!
11289        synchronized (this) {
11290            if (conn.provider.provider != provider) {
11291                // But something changed...  good enough.
11292                return;
11293            }
11294
11295            ProcessRecord proc = conn.provider.proc;
11296            if (proc == null || proc.thread == null) {
11297                // Seems like the process is already cleaned up.
11298                return;
11299            }
11300
11301            // As far as we're concerned, this is just like receiving a
11302            // death notification...  just a bit prematurely.
11303            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11304                    + ") early provider death");
11305            final long ident = Binder.clearCallingIdentity();
11306            try {
11307                appDiedLocked(proc);
11308            } finally {
11309                Binder.restoreCallingIdentity(ident);
11310            }
11311        }
11312    }
11313
11314    @Override
11315    public void appNotRespondingViaProvider(IBinder connection) {
11316        enforceCallingPermission(
11317                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11318
11319        final ContentProviderConnection conn = (ContentProviderConnection) connection;
11320        if (conn == null) {
11321            Slog.w(TAG, "ContentProviderConnection is null");
11322            return;
11323        }
11324
11325        final ProcessRecord host = conn.provider.proc;
11326        if (host == null) {
11327            Slog.w(TAG, "Failed to find hosting ProcessRecord");
11328            return;
11329        }
11330
11331        mHandler.post(new Runnable() {
11332            @Override
11333            public void run() {
11334                mAppErrors.appNotResponding(host, null, null, false,
11335                        "ContentProvider not responding");
11336            }
11337        });
11338    }
11339
11340    public final void installSystemProviders() {
11341        List<ProviderInfo> providers;
11342        synchronized (this) {
11343            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11344            providers = generateApplicationProvidersLocked(app);
11345            if (providers != null) {
11346                for (int i=providers.size()-1; i>=0; i--) {
11347                    ProviderInfo pi = (ProviderInfo)providers.get(i);
11348                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11349                        Slog.w(TAG, "Not installing system proc provider " + pi.name
11350                                + ": not system .apk");
11351                        providers.remove(i);
11352                    }
11353                }
11354            }
11355        }
11356        if (providers != null) {
11357            mSystemThread.installSystemProviders(providers);
11358        }
11359
11360        mCoreSettingsObserver = new CoreSettingsObserver(this);
11361        mFontScaleSettingObserver = new FontScaleSettingObserver();
11362
11363        //mUsageStatsService.monitorPackages();
11364    }
11365
11366    private void startPersistentApps(int matchFlags) {
11367        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11368
11369        synchronized (this) {
11370            try {
11371                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11372                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11373                for (ApplicationInfo app : apps) {
11374                    if (!"android".equals(app.packageName)) {
11375                        addAppLocked(app, false, null /* ABI override */);
11376                    }
11377                }
11378            } catch (RemoteException ex) {
11379            }
11380        }
11381    }
11382
11383    /**
11384     * When a user is unlocked, we need to install encryption-unaware providers
11385     * belonging to any running apps.
11386     */
11387    private void installEncryptionUnawareProviders(int userId) {
11388        // We're only interested in providers that are encryption unaware, and
11389        // we don't care about uninstalled apps, since there's no way they're
11390        // running at this point.
11391        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11392
11393        synchronized (this) {
11394            final int NP = mProcessNames.getMap().size();
11395            for (int ip = 0; ip < NP; ip++) {
11396                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11397                final int NA = apps.size();
11398                for (int ia = 0; ia < NA; ia++) {
11399                    final ProcessRecord app = apps.valueAt(ia);
11400                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11401
11402                    final int NG = app.pkgList.size();
11403                    for (int ig = 0; ig < NG; ig++) {
11404                        try {
11405                            final String pkgName = app.pkgList.keyAt(ig);
11406                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11407                                    .getPackageInfo(pkgName, matchFlags, userId);
11408                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11409                                for (ProviderInfo pi : pkgInfo.providers) {
11410                                    // TODO: keep in sync with generateApplicationProvidersLocked
11411                                    final boolean processMatch = Objects.equals(pi.processName,
11412                                            app.processName) || pi.multiprocess;
11413                                    final boolean userMatch = isSingleton(pi.processName,
11414                                            pi.applicationInfo, pi.name, pi.flags)
11415                                                    ? (app.userId == UserHandle.USER_SYSTEM) : true;
11416                                    if (processMatch && userMatch) {
11417                                        Log.v(TAG, "Installing " + pi);
11418                                        app.thread.scheduleInstallProvider(pi);
11419                                    } else {
11420                                        Log.v(TAG, "Skipping " + pi);
11421                                    }
11422                                }
11423                            }
11424                        } catch (RemoteException ignored) {
11425                        }
11426                    }
11427                }
11428            }
11429        }
11430    }
11431
11432    /**
11433     * Allows apps to retrieve the MIME type of a URI.
11434     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11435     * users, then it does not need permission to access the ContentProvider.
11436     * Either, it needs cross-user uri grants.
11437     *
11438     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11439     *
11440     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11441     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11442     */
11443    public String getProviderMimeType(Uri uri, int userId) {
11444        enforceNotIsolatedCaller("getProviderMimeType");
11445        final String name = uri.getAuthority();
11446        int callingUid = Binder.getCallingUid();
11447        int callingPid = Binder.getCallingPid();
11448        long ident = 0;
11449        boolean clearedIdentity = false;
11450        synchronized (this) {
11451            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11452        }
11453        if (canClearIdentity(callingPid, callingUid, userId)) {
11454            clearedIdentity = true;
11455            ident = Binder.clearCallingIdentity();
11456        }
11457        ContentProviderHolder holder = null;
11458        try {
11459            holder = getContentProviderExternalUnchecked(name, null, userId);
11460            if (holder != null) {
11461                return holder.provider.getType(uri);
11462            }
11463        } catch (RemoteException e) {
11464            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11465            return null;
11466        } catch (Exception e) {
11467            Log.w(TAG, "Exception while determining type of " + uri, e);
11468            return null;
11469        } finally {
11470            // We need to clear the identity to call removeContentProviderExternalUnchecked
11471            if (!clearedIdentity) {
11472                ident = Binder.clearCallingIdentity();
11473            }
11474            try {
11475                if (holder != null) {
11476                    removeContentProviderExternalUnchecked(name, null, userId);
11477                }
11478            } finally {
11479                Binder.restoreCallingIdentity(ident);
11480            }
11481        }
11482
11483        return null;
11484    }
11485
11486    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11487        if (UserHandle.getUserId(callingUid) == userId) {
11488            return true;
11489        }
11490        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11491                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11492                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11493                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11494                return true;
11495        }
11496        return false;
11497    }
11498
11499    // =========================================================
11500    // GLOBAL MANAGEMENT
11501    // =========================================================
11502
11503    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11504            boolean isolated, int isolatedUid) {
11505        String proc = customProcess != null ? customProcess : info.processName;
11506        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11507        final int userId = UserHandle.getUserId(info.uid);
11508        int uid = info.uid;
11509        if (isolated) {
11510            if (isolatedUid == 0) {
11511                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11512                while (true) {
11513                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11514                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11515                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11516                    }
11517                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11518                    mNextIsolatedProcessUid++;
11519                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11520                        // No process for this uid, use it.
11521                        break;
11522                    }
11523                    stepsLeft--;
11524                    if (stepsLeft <= 0) {
11525                        return null;
11526                    }
11527                }
11528            } else {
11529                // Special case for startIsolatedProcess (internal only), where
11530                // the uid of the isolated process is specified by the caller.
11531                uid = isolatedUid;
11532            }
11533
11534            // Register the isolated UID with this application so BatteryStats knows to
11535            // attribute resource usage to the application.
11536            //
11537            // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
11538            // about the process state of the isolated UID *before* it is registered with the
11539            // owning application.
11540            mBatteryStatsService.addIsolatedUid(uid, info.uid);
11541        }
11542        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11543        if (!mBooted && !mBooting
11544                && userId == UserHandle.USER_SYSTEM
11545                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11546            r.persistent = true;
11547            r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11548        }
11549        addProcessNameLocked(r);
11550        return r;
11551    }
11552
11553    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11554            String abiOverride) {
11555        ProcessRecord app;
11556        if (!isolated) {
11557            app = getProcessRecordLocked(info.processName, info.uid, true);
11558        } else {
11559            app = null;
11560        }
11561
11562        if (app == null) {
11563            app = newProcessRecordLocked(info, null, isolated, 0);
11564            updateLruProcessLocked(app, false, null);
11565            updateOomAdjLocked();
11566        }
11567
11568        // This package really, really can not be stopped.
11569        try {
11570            AppGlobals.getPackageManager().setPackageStoppedState(
11571                    info.packageName, false, UserHandle.getUserId(app.uid));
11572        } catch (RemoteException e) {
11573        } catch (IllegalArgumentException e) {
11574            Slog.w(TAG, "Failed trying to unstop package "
11575                    + info.packageName + ": " + e);
11576        }
11577
11578        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11579            app.persistent = true;
11580            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11581        }
11582        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11583            mPersistentStartingProcesses.add(app);
11584            startProcessLocked(app, "added application", app.processName, abiOverride,
11585                    null /* entryPoint */, null /* entryPointArgs */);
11586        }
11587
11588        return app;
11589    }
11590
11591    public void unhandledBack() {
11592        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11593                "unhandledBack()");
11594
11595        synchronized(this) {
11596            final long origId = Binder.clearCallingIdentity();
11597            try {
11598                getFocusedStack().unhandledBackLocked();
11599            } finally {
11600                Binder.restoreCallingIdentity(origId);
11601            }
11602        }
11603    }
11604
11605    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11606        enforceNotIsolatedCaller("openContentUri");
11607        final int userId = UserHandle.getCallingUserId();
11608        String name = uri.getAuthority();
11609        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11610        ParcelFileDescriptor pfd = null;
11611        if (cph != null) {
11612            // We record the binder invoker's uid in thread-local storage before
11613            // going to the content provider to open the file.  Later, in the code
11614            // that handles all permissions checks, we look for this uid and use
11615            // that rather than the Activity Manager's own uid.  The effect is that
11616            // we do the check against the caller's permissions even though it looks
11617            // to the content provider like the Activity Manager itself is making
11618            // the request.
11619            Binder token = new Binder();
11620            sCallerIdentity.set(new Identity(
11621                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11622            try {
11623                pfd = cph.provider.openFile(null, uri, "r", null, token);
11624            } catch (FileNotFoundException e) {
11625                // do nothing; pfd will be returned null
11626            } finally {
11627                // Ensure that whatever happens, we clean up the identity state
11628                sCallerIdentity.remove();
11629                // Ensure we're done with the provider.
11630                removeContentProviderExternalUnchecked(name, null, userId);
11631            }
11632        } else {
11633            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11634        }
11635        return pfd;
11636    }
11637
11638    // Actually is sleeping or shutting down or whatever else in the future
11639    // is an inactive state.
11640    boolean isSleepingOrShuttingDownLocked() {
11641        return isSleepingLocked() || mShuttingDown;
11642    }
11643
11644    boolean isShuttingDownLocked() {
11645        return mShuttingDown;
11646    }
11647
11648    boolean isSleepingLocked() {
11649        return mSleeping;
11650    }
11651
11652    void onWakefulnessChanged(int wakefulness) {
11653        synchronized(this) {
11654            mWakefulness = wakefulness;
11655            updateSleepIfNeededLocked();
11656        }
11657    }
11658
11659    void finishRunningVoiceLocked() {
11660        if (mRunningVoice != null) {
11661            mRunningVoice = null;
11662            mVoiceWakeLock.release();
11663            updateSleepIfNeededLocked();
11664        }
11665    }
11666
11667    void startTimeTrackingFocusedActivityLocked() {
11668        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11669            mCurAppTimeTracker.start(mFocusedActivity.packageName);
11670        }
11671    }
11672
11673    void updateSleepIfNeededLocked() {
11674        if (mSleeping && !shouldSleepLocked()) {
11675            mSleeping = false;
11676            startTimeTrackingFocusedActivityLocked();
11677            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11678            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11679            updateOomAdjLocked();
11680        } else if (!mSleeping && shouldSleepLocked()) {
11681            mSleeping = true;
11682            if (mCurAppTimeTracker != null) {
11683                mCurAppTimeTracker.stop();
11684            }
11685            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11686            mStackSupervisor.goingToSleepLocked();
11687            updateOomAdjLocked();
11688
11689            // Initialize the wake times of all processes.
11690            checkExcessivePowerUsageLocked(false);
11691            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11692            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11693            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11694        }
11695    }
11696
11697    private boolean shouldSleepLocked() {
11698        // Resume applications while running a voice interactor.
11699        if (mRunningVoice != null) {
11700            return false;
11701        }
11702
11703        // TODO: Transform the lock screen state into a sleep token instead.
11704        switch (mWakefulness) {
11705            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11706            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11707            case PowerManagerInternal.WAKEFULNESS_DOZING:
11708                // Pause applications whenever the lock screen is shown or any sleep
11709                // tokens have been acquired.
11710                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11711            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11712            default:
11713                // If we're asleep then pause applications unconditionally.
11714                return true;
11715        }
11716    }
11717
11718    /** Pokes the task persister. */
11719    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11720        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11721    }
11722
11723    /** Notifies all listeners when the task stack has changed. */
11724    void notifyTaskStackChangedLocked() {
11725        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11726        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11727        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11728        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11729    }
11730
11731    /** Notifies all listeners when an Activity is pinned. */
11732    void notifyActivityPinnedLocked() {
11733        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11734        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11735    }
11736
11737    /**
11738     * Notifies all listeners when an attempt was made to start an an activity that is already
11739     * running in the pinned stack and the activity was not actually started, but the task is
11740     * either brought to the front or a new Intent is delivered to it.
11741     */
11742    void notifyPinnedActivityRestartAttemptLocked() {
11743        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11744        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11745    }
11746
11747    /** Notifies all listeners when the pinned stack animation ends. */
11748    @Override
11749    public void notifyPinnedStackAnimationEnded() {
11750        synchronized (this) {
11751            mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11752            mHandler.obtainMessage(
11753                    NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11754        }
11755    }
11756
11757    @Override
11758    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11759        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11760    }
11761
11762    @Override
11763    public boolean shutdown(int timeout) {
11764        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11765                != PackageManager.PERMISSION_GRANTED) {
11766            throw new SecurityException("Requires permission "
11767                    + android.Manifest.permission.SHUTDOWN);
11768        }
11769
11770        boolean timedout = false;
11771
11772        synchronized(this) {
11773            mShuttingDown = true;
11774            updateEventDispatchingLocked();
11775            timedout = mStackSupervisor.shutdownLocked(timeout);
11776        }
11777
11778        mAppOpsService.shutdown();
11779        if (mUsageStatsService != null) {
11780            mUsageStatsService.prepareShutdown();
11781        }
11782        mBatteryStatsService.shutdown();
11783        synchronized (this) {
11784            mProcessStats.shutdownLocked();
11785            notifyTaskPersisterLocked(null, true);
11786        }
11787
11788        return timedout;
11789    }
11790
11791    public final void activitySlept(IBinder token) {
11792        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11793
11794        final long origId = Binder.clearCallingIdentity();
11795
11796        synchronized (this) {
11797            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11798            if (r != null) {
11799                mStackSupervisor.activitySleptLocked(r);
11800            }
11801        }
11802
11803        Binder.restoreCallingIdentity(origId);
11804    }
11805
11806    private String lockScreenShownToString() {
11807        switch (mLockScreenShown) {
11808            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11809            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11810            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11811            default: return "Unknown=" + mLockScreenShown;
11812        }
11813    }
11814
11815    void logLockScreen(String msg) {
11816        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11817                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11818                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11819                + " mSleeping=" + mSleeping);
11820    }
11821
11822    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11823        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11824        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11825        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11826            boolean wasRunningVoice = mRunningVoice != null;
11827            mRunningVoice = session;
11828            if (!wasRunningVoice) {
11829                mVoiceWakeLock.acquire();
11830                updateSleepIfNeededLocked();
11831            }
11832        }
11833    }
11834
11835    private void updateEventDispatchingLocked() {
11836        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11837    }
11838
11839    public void setLockScreenShown(boolean showing, boolean occluded) {
11840        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11841                != PackageManager.PERMISSION_GRANTED) {
11842            throw new SecurityException("Requires permission "
11843                    + android.Manifest.permission.DEVICE_POWER);
11844        }
11845
11846        synchronized(this) {
11847            long ident = Binder.clearCallingIdentity();
11848            try {
11849                if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
11850                mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11851                if (showing && occluded) {
11852                    // The lock screen is currently showing, but is occluded by a window that can
11853                    // show on top of the lock screen. In this can we want to dismiss the docked
11854                    // stack since it will be complicated/risky to try to put the activity on top
11855                    // of the lock screen in the right fullscreen configuration.
11856                    mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
11857                            mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
11858                }
11859
11860                updateSleepIfNeededLocked();
11861            } finally {
11862                Binder.restoreCallingIdentity(ident);
11863            }
11864        }
11865    }
11866
11867    @Override
11868    public void notifyLockedProfile(@UserIdInt int userId) {
11869        try {
11870            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11871                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11872            }
11873        } catch (RemoteException ex) {
11874            throw new SecurityException("Fail to check is caller a privileged app", ex);
11875        }
11876
11877        synchronized (this) {
11878            if (mStackSupervisor.isUserLockedProfile(userId)) {
11879                final long ident = Binder.clearCallingIdentity();
11880                try {
11881                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11882
11883                    // Drop locked freeform tasks out into the fullscreen stack.
11884                    // TODO: Redact the tasks in place. It's much better to keep them on the screen
11885                    //       where they were before, but in an obscured state.
11886                    mStackSupervisor.moveProfileTasksFromFreeformToFullscreenStackLocked(userId);
11887
11888                    if (mUserController.isLockScreenDisabled(currentUserId)) {
11889                        // If there is no device lock, we will show the profile's credential page.
11890                        mActivityStarter.showConfirmDeviceCredential(userId);
11891                    } else {
11892                        // Showing launcher to avoid user entering credential twice.
11893                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11894                    }
11895                } finally {
11896                    Binder.restoreCallingIdentity(ident);
11897                }
11898            }
11899        }
11900    }
11901
11902    @Override
11903    public void startConfirmDeviceCredentialIntent(Intent intent) {
11904        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11905        synchronized (this) {
11906            final long ident = Binder.clearCallingIdentity();
11907            try {
11908                mActivityStarter.startConfirmCredentialIntent(intent);
11909            } finally {
11910                Binder.restoreCallingIdentity(ident);
11911            }
11912        }
11913    }
11914
11915    @Override
11916    public void stopAppSwitches() {
11917        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11918                != PackageManager.PERMISSION_GRANTED) {
11919            throw new SecurityException("viewquires permission "
11920                    + android.Manifest.permission.STOP_APP_SWITCHES);
11921        }
11922
11923        synchronized(this) {
11924            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11925                    + APP_SWITCH_DELAY_TIME;
11926            mDidAppSwitch = false;
11927            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11928            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11929            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11930        }
11931    }
11932
11933    public void resumeAppSwitches() {
11934        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11935                != PackageManager.PERMISSION_GRANTED) {
11936            throw new SecurityException("Requires permission "
11937                    + android.Manifest.permission.STOP_APP_SWITCHES);
11938        }
11939
11940        synchronized(this) {
11941            // Note that we don't execute any pending app switches... we will
11942            // let those wait until either the timeout, or the next start
11943            // activity request.
11944            mAppSwitchesAllowedTime = 0;
11945        }
11946    }
11947
11948    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11949            int callingPid, int callingUid, String name) {
11950        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11951            return true;
11952        }
11953
11954        int perm = checkComponentPermission(
11955                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11956                sourceUid, -1, true);
11957        if (perm == PackageManager.PERMISSION_GRANTED) {
11958            return true;
11959        }
11960
11961        // If the actual IPC caller is different from the logical source, then
11962        // also see if they are allowed to control app switches.
11963        if (callingUid != -1 && callingUid != sourceUid) {
11964            perm = checkComponentPermission(
11965                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11966                    callingUid, -1, true);
11967            if (perm == PackageManager.PERMISSION_GRANTED) {
11968                return true;
11969            }
11970        }
11971
11972        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11973        return false;
11974    }
11975
11976    public void setDebugApp(String packageName, boolean waitForDebugger,
11977            boolean persistent) {
11978        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11979                "setDebugApp()");
11980
11981        long ident = Binder.clearCallingIdentity();
11982        try {
11983            // Note that this is not really thread safe if there are multiple
11984            // callers into it at the same time, but that's not a situation we
11985            // care about.
11986            if (persistent) {
11987                final ContentResolver resolver = mContext.getContentResolver();
11988                Settings.Global.putString(
11989                    resolver, Settings.Global.DEBUG_APP,
11990                    packageName);
11991                Settings.Global.putInt(
11992                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11993                    waitForDebugger ? 1 : 0);
11994            }
11995
11996            synchronized (this) {
11997                if (!persistent) {
11998                    mOrigDebugApp = mDebugApp;
11999                    mOrigWaitForDebugger = mWaitForDebugger;
12000                }
12001                mDebugApp = packageName;
12002                mWaitForDebugger = waitForDebugger;
12003                mDebugTransient = !persistent;
12004                if (packageName != null) {
12005                    forceStopPackageLocked(packageName, -1, false, false, true, true,
12006                            false, UserHandle.USER_ALL, "set debug app");
12007                }
12008            }
12009        } finally {
12010            Binder.restoreCallingIdentity(ident);
12011        }
12012    }
12013
12014    void setTrackAllocationApp(ApplicationInfo app, String processName) {
12015        synchronized (this) {
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
12023            mTrackAllocationApp = processName;
12024        }
12025    }
12026
12027    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
12028        synchronized (this) {
12029            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12030            if (!isDebuggable) {
12031                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12032                    throw new SecurityException("Process not debuggable: " + app.packageName);
12033                }
12034            }
12035            mProfileApp = processName;
12036            mProfileFile = profilerInfo.profileFile;
12037            if (mProfileFd != null) {
12038                try {
12039                    mProfileFd.close();
12040                } catch (IOException e) {
12041                }
12042                mProfileFd = null;
12043            }
12044            mProfileFd = profilerInfo.profileFd;
12045            mSamplingInterval = profilerInfo.samplingInterval;
12046            mAutoStopProfiler = profilerInfo.autoStopProfiler;
12047            mStreamingOutput = profilerInfo.streamingOutput;
12048            mProfileType = 0;
12049        }
12050    }
12051
12052    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
12053        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12054        if (!isDebuggable) {
12055            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12056                throw new SecurityException("Process not debuggable: " + app.packageName);
12057            }
12058        }
12059        mNativeDebuggingApp = processName;
12060    }
12061
12062    @Override
12063    public void setAlwaysFinish(boolean enabled) {
12064        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
12065                "setAlwaysFinish()");
12066
12067        long ident = Binder.clearCallingIdentity();
12068        try {
12069            Settings.Global.putInt(
12070                    mContext.getContentResolver(),
12071                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
12072
12073            synchronized (this) {
12074                mAlwaysFinishActivities = enabled;
12075            }
12076        } finally {
12077            Binder.restoreCallingIdentity(ident);
12078        }
12079    }
12080
12081    @Override
12082    public void setLenientBackgroundCheck(boolean enabled) {
12083        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
12084                "setLenientBackgroundCheck()");
12085
12086        long ident = Binder.clearCallingIdentity();
12087        try {
12088            Settings.Global.putInt(
12089                    mContext.getContentResolver(),
12090                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
12091
12092            synchronized (this) {
12093                mLenientBackgroundCheck = enabled;
12094            }
12095        } finally {
12096            Binder.restoreCallingIdentity(ident);
12097        }
12098    }
12099
12100    @Override
12101    public void setActivityController(IActivityController controller, boolean imAMonkey) {
12102        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12103                "setActivityController()");
12104        synchronized (this) {
12105            mController = controller;
12106            mControllerIsAMonkey = imAMonkey;
12107            Watchdog.getInstance().setActivityController(controller);
12108        }
12109    }
12110
12111    @Override
12112    public void setUserIsMonkey(boolean userIsMonkey) {
12113        synchronized (this) {
12114            synchronized (mPidsSelfLocked) {
12115                final int callingPid = Binder.getCallingPid();
12116                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
12117                if (precessRecord == null) {
12118                    throw new SecurityException("Unknown process: " + callingPid);
12119                }
12120                if (precessRecord.instrumentationUiAutomationConnection  == null) {
12121                    throw new SecurityException("Only an instrumentation process "
12122                            + "with a UiAutomation can call setUserIsMonkey");
12123                }
12124            }
12125            mUserIsMonkey = userIsMonkey;
12126        }
12127    }
12128
12129    @Override
12130    public boolean isUserAMonkey() {
12131        synchronized (this) {
12132            // If there is a controller also implies the user is a monkey.
12133            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12134        }
12135    }
12136
12137    public void requestBugReport(int bugreportType) {
12138        String service = null;
12139        switch (bugreportType) {
12140            case ActivityManager.BUGREPORT_OPTION_FULL:
12141                service = "bugreport";
12142                break;
12143            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12144                service = "bugreportplus";
12145                break;
12146            case ActivityManager.BUGREPORT_OPTION_REMOTE:
12147                service = "bugreportremote";
12148                break;
12149            case ActivityManager.BUGREPORT_OPTION_WEAR:
12150                service = "bugreportwear";
12151                break;
12152        }
12153        if (service == null) {
12154            throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12155                    + bugreportType);
12156        }
12157        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12158        SystemProperties.set("ctl.start", service);
12159    }
12160
12161    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12162        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12163    }
12164
12165    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12166        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
12167            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12168        }
12169        return KEY_DISPATCHING_TIMEOUT;
12170    }
12171
12172    @Override
12173    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12174        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12175                != PackageManager.PERMISSION_GRANTED) {
12176            throw new SecurityException("Requires permission "
12177                    + android.Manifest.permission.FILTER_EVENTS);
12178        }
12179        ProcessRecord proc;
12180        long timeout;
12181        synchronized (this) {
12182            synchronized (mPidsSelfLocked) {
12183                proc = mPidsSelfLocked.get(pid);
12184            }
12185            timeout = getInputDispatchingTimeoutLocked(proc);
12186        }
12187
12188        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12189            return -1;
12190        }
12191
12192        return timeout;
12193    }
12194
12195    /**
12196     * Handle input dispatching timeouts.
12197     * Returns whether input dispatching should be aborted or not.
12198     */
12199    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12200            final ActivityRecord activity, final ActivityRecord parent,
12201            final boolean aboveSystem, String reason) {
12202        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12203                != PackageManager.PERMISSION_GRANTED) {
12204            throw new SecurityException("Requires permission "
12205                    + android.Manifest.permission.FILTER_EVENTS);
12206        }
12207
12208        final String annotation;
12209        if (reason == null) {
12210            annotation = "Input dispatching timed out";
12211        } else {
12212            annotation = "Input dispatching timed out (" + reason + ")";
12213        }
12214
12215        if (proc != null) {
12216            synchronized (this) {
12217                if (proc.debugging) {
12218                    return false;
12219                }
12220
12221                if (mDidDexOpt) {
12222                    // Give more time since we were dexopting.
12223                    mDidDexOpt = false;
12224                    return false;
12225                }
12226
12227                if (proc.instrumentationClass != null) {
12228                    Bundle info = new Bundle();
12229                    info.putString("shortMsg", "keyDispatchingTimedOut");
12230                    info.putString("longMsg", annotation);
12231                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12232                    return true;
12233                }
12234            }
12235            mHandler.post(new Runnable() {
12236                @Override
12237                public void run() {
12238                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12239                }
12240            });
12241        }
12242
12243        return true;
12244    }
12245
12246    @Override
12247    public Bundle getAssistContextExtras(int requestType) {
12248        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12249                null, null, true /* focused */, true /* newSessionId */,
12250                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
12251        if (pae == null) {
12252            return null;
12253        }
12254        synchronized (pae) {
12255            while (!pae.haveResult) {
12256                try {
12257                    pae.wait();
12258                } catch (InterruptedException e) {
12259                }
12260            }
12261        }
12262        synchronized (this) {
12263            buildAssistBundleLocked(pae, pae.result);
12264            mPendingAssistExtras.remove(pae);
12265            mUiHandler.removeCallbacks(pae);
12266        }
12267        return pae.extras;
12268    }
12269
12270    @Override
12271    public boolean isAssistDataAllowedOnCurrentActivity() {
12272        int userId;
12273        synchronized (this) {
12274            userId = mUserController.getCurrentUserIdLocked();
12275            ActivityRecord activity = getFocusedStack().topActivity();
12276            if (activity == null) {
12277                return false;
12278            }
12279            userId = activity.userId;
12280        }
12281        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12282                Context.DEVICE_POLICY_SERVICE);
12283        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12284    }
12285
12286    @Override
12287    public boolean showAssistFromActivity(IBinder token, Bundle args) {
12288        long ident = Binder.clearCallingIdentity();
12289        try {
12290            synchronized (this) {
12291                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12292                ActivityRecord top = getFocusedStack().topActivity();
12293                if (top != caller) {
12294                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12295                            + " is not current top " + top);
12296                    return false;
12297                }
12298                if (!top.nowVisible) {
12299                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12300                            + " is not visible");
12301                    return false;
12302                }
12303            }
12304            AssistUtils utils = new AssistUtils(mContext);
12305            return utils.showSessionForActiveService(args,
12306                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
12307        } finally {
12308            Binder.restoreCallingIdentity(ident);
12309        }
12310    }
12311
12312    @Override
12313    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12314            Bundle receiverExtras,
12315            IBinder activityToken, boolean focused, boolean newSessionId) {
12316        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12317                activityToken, focused, newSessionId,
12318                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
12319                != null;
12320    }
12321
12322    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12323            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12324            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12325        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12326                "enqueueAssistContext()");
12327        synchronized (this) {
12328            ActivityRecord activity = getFocusedStack().topActivity();
12329            if (activity == null) {
12330                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12331                return null;
12332            }
12333            if (activity.app == null || activity.app.thread == null) {
12334                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12335                return null;
12336            }
12337            if (focused) {
12338                if (activityToken != null) {
12339                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12340                    if (activity != caller) {
12341                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12342                                + " is not current top " + activity);
12343                        return null;
12344                    }
12345                }
12346            } else {
12347                activity = ActivityRecord.forTokenLocked(activityToken);
12348                if (activity == null) {
12349                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12350                            + " couldn't be found");
12351                    return null;
12352                }
12353            }
12354
12355            PendingAssistExtras pae;
12356            Bundle extras = new Bundle();
12357            if (args != null) {
12358                extras.putAll(args);
12359            }
12360            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12361            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12362            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12363                    userHandle);
12364            // Increment the sessionId if necessary
12365            if (newSessionId) {
12366                mViSessionId++;
12367            }
12368            try {
12369                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12370                        requestType, mViSessionId);
12371                mPendingAssistExtras.add(pae);
12372                mUiHandler.postDelayed(pae, timeout);
12373            } catch (RemoteException e) {
12374                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12375                return null;
12376            }
12377            return pae;
12378        }
12379    }
12380
12381    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12382        IResultReceiver receiver;
12383        synchronized (this) {
12384            mPendingAssistExtras.remove(pae);
12385            receiver = pae.receiver;
12386        }
12387        if (receiver != null) {
12388            // Caller wants result sent back to them.
12389            Bundle sendBundle = new Bundle();
12390            // At least return the receiver extras
12391            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12392                    pae.receiverExtras);
12393            try {
12394                pae.receiver.send(0, sendBundle);
12395            } catch (RemoteException e) {
12396            }
12397        }
12398    }
12399
12400    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12401        if (result != null) {
12402            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12403        }
12404        if (pae.hint != null) {
12405            pae.extras.putBoolean(pae.hint, true);
12406        }
12407    }
12408
12409    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12410            AssistContent content, Uri referrer) {
12411        PendingAssistExtras pae = (PendingAssistExtras)token;
12412        synchronized (pae) {
12413            pae.result = extras;
12414            pae.structure = structure;
12415            pae.content = content;
12416            if (referrer != null) {
12417                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12418            }
12419            pae.haveResult = true;
12420            pae.notifyAll();
12421            if (pae.intent == null && pae.receiver == null) {
12422                // Caller is just waiting for the result.
12423                return;
12424            }
12425        }
12426
12427        // We are now ready to launch the assist activity.
12428        IResultReceiver sendReceiver = null;
12429        Bundle sendBundle = null;
12430        synchronized (this) {
12431            buildAssistBundleLocked(pae, extras);
12432            boolean exists = mPendingAssistExtras.remove(pae);
12433            mUiHandler.removeCallbacks(pae);
12434            if (!exists) {
12435                // Timed out.
12436                return;
12437            }
12438            if ((sendReceiver=pae.receiver) != null) {
12439                // Caller wants result sent back to them.
12440                sendBundle = new Bundle();
12441                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12442                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12443                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12444                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12445                        pae.receiverExtras);
12446            }
12447        }
12448        if (sendReceiver != null) {
12449            try {
12450                sendReceiver.send(0, sendBundle);
12451            } catch (RemoteException e) {
12452            }
12453            return;
12454        }
12455
12456        long ident = Binder.clearCallingIdentity();
12457        try {
12458            pae.intent.replaceExtras(pae.extras);
12459            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12460                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12461                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12462            closeSystemDialogs("assist");
12463            try {
12464                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12465            } catch (ActivityNotFoundException e) {
12466                Slog.w(TAG, "No activity to handle assist action.", e);
12467            }
12468        } finally {
12469            Binder.restoreCallingIdentity(ident);
12470        }
12471    }
12472
12473    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12474            Bundle args) {
12475        return enqueueAssistContext(requestType, intent, hint, null, null, null,
12476                true /* focused */, true /* newSessionId */,
12477                userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12478    }
12479
12480    public void registerProcessObserver(IProcessObserver observer) {
12481        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12482                "registerProcessObserver()");
12483        synchronized (this) {
12484            mProcessObservers.register(observer);
12485        }
12486    }
12487
12488    @Override
12489    public void unregisterProcessObserver(IProcessObserver observer) {
12490        synchronized (this) {
12491            mProcessObservers.unregister(observer);
12492        }
12493    }
12494
12495    @Override
12496    public void registerUidObserver(IUidObserver observer, int which) {
12497        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12498                "registerUidObserver()");
12499        synchronized (this) {
12500            mUidObservers.register(observer, which);
12501        }
12502    }
12503
12504    @Override
12505    public void unregisterUidObserver(IUidObserver observer) {
12506        synchronized (this) {
12507            mUidObservers.unregister(observer);
12508        }
12509    }
12510
12511    @Override
12512    public boolean convertFromTranslucent(IBinder token) {
12513        final long origId = Binder.clearCallingIdentity();
12514        try {
12515            synchronized (this) {
12516                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12517                if (r == null) {
12518                    return false;
12519                }
12520                final boolean translucentChanged = r.changeWindowTranslucency(true);
12521                if (translucentChanged) {
12522                    r.task.stack.releaseBackgroundResources(r);
12523                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12524                }
12525                mWindowManager.setAppFullscreen(token, true);
12526                return translucentChanged;
12527            }
12528        } finally {
12529            Binder.restoreCallingIdentity(origId);
12530        }
12531    }
12532
12533    @Override
12534    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12535        final long origId = Binder.clearCallingIdentity();
12536        try {
12537            synchronized (this) {
12538                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12539                if (r == null) {
12540                    return false;
12541                }
12542                int index = r.task.mActivities.lastIndexOf(r);
12543                if (index > 0) {
12544                    ActivityRecord under = r.task.mActivities.get(index - 1);
12545                    under.returningOptions = options;
12546                }
12547                final boolean translucentChanged = r.changeWindowTranslucency(false);
12548                if (translucentChanged) {
12549                    r.task.stack.convertActivityToTranslucent(r);
12550                }
12551                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12552                mWindowManager.setAppFullscreen(token, false);
12553                return translucentChanged;
12554            }
12555        } finally {
12556            Binder.restoreCallingIdentity(origId);
12557        }
12558    }
12559
12560    @Override
12561    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12562        final long origId = Binder.clearCallingIdentity();
12563        try {
12564            synchronized (this) {
12565                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12566                if (r != null) {
12567                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12568                }
12569            }
12570            return false;
12571        } finally {
12572            Binder.restoreCallingIdentity(origId);
12573        }
12574    }
12575
12576    @Override
12577    public boolean isBackgroundVisibleBehind(IBinder token) {
12578        final long origId = Binder.clearCallingIdentity();
12579        try {
12580            synchronized (this) {
12581                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12582                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12583                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12584                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12585                return visible;
12586            }
12587        } finally {
12588            Binder.restoreCallingIdentity(origId);
12589        }
12590    }
12591
12592    @Override
12593    public ActivityOptions getActivityOptions(IBinder token) {
12594        final long origId = Binder.clearCallingIdentity();
12595        try {
12596            synchronized (this) {
12597                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12598                if (r != null) {
12599                    final ActivityOptions activityOptions = r.pendingOptions;
12600                    r.pendingOptions = null;
12601                    return activityOptions;
12602                }
12603                return null;
12604            }
12605        } finally {
12606            Binder.restoreCallingIdentity(origId);
12607        }
12608    }
12609
12610    @Override
12611    public void setImmersive(IBinder token, boolean immersive) {
12612        synchronized(this) {
12613            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12614            if (r == null) {
12615                throw new IllegalArgumentException();
12616            }
12617            r.immersive = immersive;
12618
12619            // update associated state if we're frontmost
12620            if (r == mFocusedActivity) {
12621                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12622                applyUpdateLockStateLocked(r);
12623            }
12624        }
12625    }
12626
12627    @Override
12628    public boolean isImmersive(IBinder token) {
12629        synchronized (this) {
12630            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12631            if (r == null) {
12632                throw new IllegalArgumentException();
12633            }
12634            return r.immersive;
12635        }
12636    }
12637
12638    public void setVrThread(int tid) {
12639        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12640            throw new UnsupportedOperationException("VR mode not supported on this device!");
12641        }
12642
12643        synchronized (this) {
12644            ProcessRecord proc;
12645            synchronized (mPidsSelfLocked) {
12646                final int pid = Binder.getCallingPid();
12647                proc = mPidsSelfLocked.get(pid);
12648
12649                if (proc != null && mInVrMode && tid >= 0) {
12650                    // ensure the tid belongs to the process
12651                    if (!Process.isThreadInProcess(pid, tid)) {
12652                        throw new IllegalArgumentException("VR thread does not belong to process");
12653                    }
12654
12655                    // reset existing VR thread to CFS if this thread still exists and belongs to
12656                    // the calling process
12657                    if (proc.vrThreadTid != 0
12658                            && Process.isThreadInProcess(pid, proc.vrThreadTid)) {
12659                        try {
12660                            Process.setThreadScheduler(proc.vrThreadTid, Process.SCHED_OTHER, 0);
12661                        } catch (IllegalArgumentException e) {
12662                            // Ignore this.  Only occurs in race condition where previous VR thread
12663                            // was destroyed during this method call.
12664                        }
12665                    }
12666
12667                    proc.vrThreadTid = tid;
12668
12669                    // promote to FIFO now if the tid is non-zero
12670                    try {
12671                        if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
12672                            proc.vrThreadTid > 0) {
12673                            Process.setThreadScheduler(proc.vrThreadTid,
12674                                Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12675                        }
12676                    } catch (IllegalArgumentException e) {
12677                        Slog.e(TAG, "Failed to set scheduling policy, thread does"
12678                               + " not exist:\n" + e);
12679                    }
12680                }
12681            }
12682        }
12683    }
12684
12685    @Override
12686    public void setRenderThread(int tid) {
12687        synchronized (this) {
12688            ProcessRecord proc;
12689            synchronized (mPidsSelfLocked) {
12690                int pid = Binder.getCallingPid();
12691                proc = mPidsSelfLocked.get(pid);
12692                if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
12693                    // ensure the tid belongs to the process
12694                    if (!Process.isThreadInProcess(pid, tid)) {
12695                        throw new IllegalArgumentException(
12696                            "Render thread does not belong to process");
12697                    }
12698                    proc.renderThreadTid = tid;
12699                    if (DEBUG_OOM_ADJ) {
12700                        Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
12701                    }
12702                    // promote to FIFO now
12703                    if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
12704                        if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
12705                        if (mUseFifoUiScheduling) {
12706                            Process.setThreadScheduler(proc.renderThreadTid,
12707                                Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12708                        } else {
12709                            Process.setThreadPriority(proc.renderThreadTid, -10);
12710                        }
12711                    }
12712                } else {
12713                    if (DEBUG_OOM_ADJ) {
12714                        Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
12715                               "PID: " + pid + ", TID: " + tid + " FIFO: " +
12716                               mUseFifoUiScheduling);
12717                    }
12718                }
12719            }
12720        }
12721    }
12722
12723    @Override
12724    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12725        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12726            throw new UnsupportedOperationException("VR mode not supported on this device!");
12727        }
12728
12729        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12730
12731        ActivityRecord r;
12732        synchronized (this) {
12733            r = ActivityRecord.isInStackLocked(token);
12734        }
12735
12736        if (r == null) {
12737            throw new IllegalArgumentException();
12738        }
12739
12740        int err;
12741        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12742                VrManagerInternal.NO_ERROR) {
12743            return err;
12744        }
12745
12746        synchronized(this) {
12747            r.requestedVrComponent = (enabled) ? packageName : null;
12748
12749            // Update associated state if this activity is currently focused
12750            if (r == mFocusedActivity) {
12751                applyUpdateVrModeLocked(r);
12752            }
12753            return 0;
12754        }
12755    }
12756
12757    @Override
12758    public boolean isVrModePackageEnabled(ComponentName packageName) {
12759        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12760            throw new UnsupportedOperationException("VR mode not supported on this device!");
12761        }
12762
12763        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12764
12765        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12766                VrManagerInternal.NO_ERROR;
12767    }
12768
12769    public boolean isTopActivityImmersive() {
12770        enforceNotIsolatedCaller("startActivity");
12771        synchronized (this) {
12772            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12773            return (r != null) ? r.immersive : false;
12774        }
12775    }
12776
12777    @Override
12778    public boolean isTopOfTask(IBinder token) {
12779        synchronized (this) {
12780            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12781            if (r == null) {
12782                throw new IllegalArgumentException();
12783            }
12784            return r.task.getTopActivity() == r;
12785        }
12786    }
12787
12788    @Override
12789    public void setHasTopUi(boolean hasTopUi) throws RemoteException {
12790        if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
12791            String msg = "Permission Denial: setHasTopUi() from pid="
12792                    + Binder.getCallingPid()
12793                    + ", uid=" + Binder.getCallingUid()
12794                    + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
12795            Slog.w(TAG, msg);
12796            throw new SecurityException(msg);
12797        }
12798        final int pid = Binder.getCallingPid();
12799        final long origId = Binder.clearCallingIdentity();
12800        try {
12801            synchronized (this) {
12802                boolean changed = false;
12803                ProcessRecord pr;
12804                synchronized (mPidsSelfLocked) {
12805                    pr = mPidsSelfLocked.get(pid);
12806                    if (pr == null) {
12807                        Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
12808                        return;
12809                    }
12810                    if (pr.hasTopUi != hasTopUi) {
12811                        Slog.i(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
12812                        pr.hasTopUi = hasTopUi;
12813                        changed = true;
12814                    }
12815                }
12816                if (changed) {
12817                    updateOomAdjLocked(pr);
12818                }
12819            }
12820        } finally {
12821            Binder.restoreCallingIdentity(origId);
12822        }
12823    }
12824
12825    public final void enterSafeMode() {
12826        synchronized(this) {
12827            // It only makes sense to do this before the system is ready
12828            // and started launching other packages.
12829            if (!mSystemReady) {
12830                try {
12831                    AppGlobals.getPackageManager().enterSafeMode();
12832                } catch (RemoteException e) {
12833                }
12834            }
12835
12836            mSafeMode = true;
12837        }
12838    }
12839
12840    public final void showSafeModeOverlay() {
12841        View v = LayoutInflater.from(mContext).inflate(
12842                com.android.internal.R.layout.safe_mode, null);
12843        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12844        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12845        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12846        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12847        lp.gravity = Gravity.BOTTOM | Gravity.START;
12848        lp.format = v.getBackground().getOpacity();
12849        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12850                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12851        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12852        ((WindowManager)mContext.getSystemService(
12853                Context.WINDOW_SERVICE)).addView(v, lp);
12854    }
12855
12856    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12857        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12858            return;
12859        }
12860        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12861        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12862        synchronized (stats) {
12863            if (mBatteryStatsService.isOnBattery()) {
12864                mBatteryStatsService.enforceCallingPermission();
12865                int MY_UID = Binder.getCallingUid();
12866                final int uid;
12867                if (sender == null) {
12868                    uid = sourceUid;
12869                } else {
12870                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12871                }
12872                BatteryStatsImpl.Uid.Pkg pkg =
12873                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12874                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12875                pkg.noteWakeupAlarmLocked(tag);
12876            }
12877        }
12878    }
12879
12880    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12881        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12882            return;
12883        }
12884        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12885        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12886        synchronized (stats) {
12887            mBatteryStatsService.enforceCallingPermission();
12888            int MY_UID = Binder.getCallingUid();
12889            final int uid;
12890            if (sender == null) {
12891                uid = sourceUid;
12892            } else {
12893                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12894            }
12895            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12896        }
12897    }
12898
12899    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12900        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12901            return;
12902        }
12903        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12904        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12905        synchronized (stats) {
12906            mBatteryStatsService.enforceCallingPermission();
12907            int MY_UID = Binder.getCallingUid();
12908            final int uid;
12909            if (sender == null) {
12910                uid = sourceUid;
12911            } else {
12912                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12913            }
12914            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12915        }
12916    }
12917
12918    public boolean killPids(int[] pids, String pReason, boolean secure) {
12919        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12920            throw new SecurityException("killPids only available to the system");
12921        }
12922        String reason = (pReason == null) ? "Unknown" : pReason;
12923        // XXX Note: don't acquire main activity lock here, because the window
12924        // manager calls in with its locks held.
12925
12926        boolean killed = false;
12927        synchronized (mPidsSelfLocked) {
12928            int worstType = 0;
12929            for (int i=0; i<pids.length; i++) {
12930                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12931                if (proc != null) {
12932                    int type = proc.setAdj;
12933                    if (type > worstType) {
12934                        worstType = type;
12935                    }
12936                }
12937            }
12938
12939            // If the worst oom_adj is somewhere in the cached proc LRU range,
12940            // then constrain it so we will kill all cached procs.
12941            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12942                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12943                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12944            }
12945
12946            // If this is not a secure call, don't let it kill processes that
12947            // are important.
12948            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12949                worstType = ProcessList.SERVICE_ADJ;
12950            }
12951
12952            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12953            for (int i=0; i<pids.length; i++) {
12954                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12955                if (proc == null) {
12956                    continue;
12957                }
12958                int adj = proc.setAdj;
12959                if (adj >= worstType && !proc.killedByAm) {
12960                    proc.kill(reason, true);
12961                    killed = true;
12962                }
12963            }
12964        }
12965        return killed;
12966    }
12967
12968    @Override
12969    public void killUid(int appId, int userId, String reason) {
12970        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12971        synchronized (this) {
12972            final long identity = Binder.clearCallingIdentity();
12973            try {
12974                killPackageProcessesLocked(null, appId, userId,
12975                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12976                        reason != null ? reason : "kill uid");
12977            } finally {
12978                Binder.restoreCallingIdentity(identity);
12979            }
12980        }
12981    }
12982
12983    @Override
12984    public boolean killProcessesBelowForeground(String reason) {
12985        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12986            throw new SecurityException("killProcessesBelowForeground() only available to system");
12987        }
12988
12989        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12990    }
12991
12992    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12993        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12994            throw new SecurityException("killProcessesBelowAdj() only available to system");
12995        }
12996
12997        boolean killed = false;
12998        synchronized (mPidsSelfLocked) {
12999            final int size = mPidsSelfLocked.size();
13000            for (int i = 0; i < size; i++) {
13001                final int pid = mPidsSelfLocked.keyAt(i);
13002                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13003                if (proc == null) continue;
13004
13005                final int adj = proc.setAdj;
13006                if (adj > belowAdj && !proc.killedByAm) {
13007                    proc.kill(reason, true);
13008                    killed = true;
13009                }
13010            }
13011        }
13012        return killed;
13013    }
13014
13015    @Override
13016    public void hang(final IBinder who, boolean allowRestart) {
13017        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13018                != PackageManager.PERMISSION_GRANTED) {
13019            throw new SecurityException("Requires permission "
13020                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13021        }
13022
13023        final IBinder.DeathRecipient death = new DeathRecipient() {
13024            @Override
13025            public void binderDied() {
13026                synchronized (this) {
13027                    notifyAll();
13028                }
13029            }
13030        };
13031
13032        try {
13033            who.linkToDeath(death, 0);
13034        } catch (RemoteException e) {
13035            Slog.w(TAG, "hang: given caller IBinder is already dead.");
13036            return;
13037        }
13038
13039        synchronized (this) {
13040            Watchdog.getInstance().setAllowRestart(allowRestart);
13041            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
13042            synchronized (death) {
13043                while (who.isBinderAlive()) {
13044                    try {
13045                        death.wait();
13046                    } catch (InterruptedException e) {
13047                    }
13048                }
13049            }
13050            Watchdog.getInstance().setAllowRestart(true);
13051        }
13052    }
13053
13054    @Override
13055    public void restart() {
13056        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13057                != PackageManager.PERMISSION_GRANTED) {
13058            throw new SecurityException("Requires permission "
13059                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13060        }
13061
13062        Log.i(TAG, "Sending shutdown broadcast...");
13063
13064        BroadcastReceiver br = new BroadcastReceiver() {
13065            @Override public void onReceive(Context context, Intent intent) {
13066                // Now the broadcast is done, finish up the low-level shutdown.
13067                Log.i(TAG, "Shutting down activity manager...");
13068                shutdown(10000);
13069                Log.i(TAG, "Shutdown complete, restarting!");
13070                Process.killProcess(Process.myPid());
13071                System.exit(10);
13072            }
13073        };
13074
13075        // First send the high-level shut down broadcast.
13076        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
13077        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
13078        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
13079        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
13080        mContext.sendOrderedBroadcastAsUser(intent,
13081                UserHandle.ALL, null, br, mHandler, 0, null, null);
13082        */
13083        br.onReceive(mContext, intent);
13084    }
13085
13086    private long getLowRamTimeSinceIdle(long now) {
13087        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
13088    }
13089
13090    @Override
13091    public void performIdleMaintenance() {
13092        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13093                != PackageManager.PERMISSION_GRANTED) {
13094            throw new SecurityException("Requires permission "
13095                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13096        }
13097
13098        synchronized (this) {
13099            final long now = SystemClock.uptimeMillis();
13100            final long timeSinceLastIdle = now - mLastIdleTime;
13101            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
13102            mLastIdleTime = now;
13103            mLowRamTimeSinceLastIdle = 0;
13104            if (mLowRamStartTime != 0) {
13105                mLowRamStartTime = now;
13106            }
13107
13108            StringBuilder sb = new StringBuilder(128);
13109            sb.append("Idle maintenance over ");
13110            TimeUtils.formatDuration(timeSinceLastIdle, sb);
13111            sb.append(" low RAM for ");
13112            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13113            Slog.i(TAG, sb.toString());
13114
13115            // If at least 1/3 of our time since the last idle period has been spent
13116            // with RAM low, then we want to kill processes.
13117            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
13118
13119            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13120                ProcessRecord proc = mLruProcesses.get(i);
13121                if (proc.notCachedSinceIdle) {
13122                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
13123                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
13124                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
13125                        if (doKilling && proc.initialIdlePss != 0
13126                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
13127                            sb = new StringBuilder(128);
13128                            sb.append("Kill");
13129                            sb.append(proc.processName);
13130                            sb.append(" in idle maint: pss=");
13131                            sb.append(proc.lastPss);
13132                            sb.append(", swapPss=");
13133                            sb.append(proc.lastSwapPss);
13134                            sb.append(", initialPss=");
13135                            sb.append(proc.initialIdlePss);
13136                            sb.append(", period=");
13137                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
13138                            sb.append(", lowRamPeriod=");
13139                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13140                            Slog.wtfQuiet(TAG, sb.toString());
13141                            proc.kill("idle maint (pss " + proc.lastPss
13142                                    + " from " + proc.initialIdlePss + ")", true);
13143                        }
13144                    }
13145                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
13146                        && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
13147                    proc.notCachedSinceIdle = true;
13148                    proc.initialIdlePss = 0;
13149                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
13150                            mTestPssMode, isSleepingLocked(), now);
13151                }
13152            }
13153
13154            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
13155            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
13156        }
13157    }
13158
13159    @Override
13160    public void sendIdleJobTrigger() {
13161        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13162                != PackageManager.PERMISSION_GRANTED) {
13163            throw new SecurityException("Requires permission "
13164                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13165        }
13166
13167        final long ident = Binder.clearCallingIdentity();
13168        try {
13169            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
13170                    .setPackage("android")
13171                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13172            broadcastIntent(null, intent, null, null, 0, null, null, null,
13173                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
13174        } finally {
13175            Binder.restoreCallingIdentity(ident);
13176        }
13177    }
13178
13179    private void retrieveSettings() {
13180        final ContentResolver resolver = mContext.getContentResolver();
13181        final boolean freeformWindowManagement =
13182                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
13183                        || Settings.Global.getInt(
13184                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
13185        final boolean supportsPictureInPicture =
13186                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
13187
13188        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
13189        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
13190        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
13191        final boolean alwaysFinishActivities =
13192                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
13193        final boolean lenientBackgroundCheck =
13194                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
13195        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
13196        final boolean forceResizable = Settings.Global.getInt(
13197                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
13198        final boolean supportsLeanbackOnly =
13199                mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
13200
13201        // Transfer any global setting for forcing RTL layout, into a System Property
13202        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
13203
13204        final Configuration configuration = new Configuration();
13205        Settings.System.getConfiguration(resolver, configuration);
13206        if (forceRtl) {
13207            // This will take care of setting the correct layout direction flags
13208            configuration.setLayoutDirection(configuration.locale);
13209        }
13210
13211        synchronized (this) {
13212            mDebugApp = mOrigDebugApp = debugApp;
13213            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
13214            mAlwaysFinishActivities = alwaysFinishActivities;
13215            mLenientBackgroundCheck = lenientBackgroundCheck;
13216            mSupportsLeanbackOnly = supportsLeanbackOnly;
13217            mForceResizableActivities = forceResizable;
13218            mWindowManager.setForceResizableTasks(mForceResizableActivities);
13219            if (supportsMultiWindow || forceResizable) {
13220                mSupportsMultiWindow = true;
13221                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
13222                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
13223            } else {
13224                mSupportsMultiWindow = false;
13225                mSupportsFreeformWindowManagement = false;
13226                mSupportsPictureInPicture = false;
13227            }
13228            // This happens before any activities are started, so we can
13229            // change mConfiguration in-place.
13230            updateConfigurationLocked(configuration, null, true);
13231            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
13232                    "Initial config: " + mConfiguration);
13233
13234            // Load resources only after the current configuration has been set.
13235            final Resources res = mContext.getResources();
13236            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
13237            mThumbnailWidth = res.getDimensionPixelSize(
13238                    com.android.internal.R.dimen.thumbnail_width);
13239            mThumbnailHeight = res.getDimensionPixelSize(
13240                    com.android.internal.R.dimen.thumbnail_height);
13241            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
13242                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
13243            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
13244                    com.android.internal.R.string.config_appsNotReportingCrashes));
13245            if ((mConfiguration.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
13246                mFullscreenThumbnailScale = (float) res
13247                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
13248                    (float) mConfiguration.screenWidthDp;
13249            } else {
13250                mFullscreenThumbnailScale = res.getFraction(
13251                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
13252            }
13253        }
13254    }
13255
13256    public boolean testIsSystemReady() {
13257        // no need to synchronize(this) just to read & return the value
13258        return mSystemReady;
13259    }
13260
13261    public void systemReady(final Runnable goingCallback) {
13262        synchronized(this) {
13263            if (mSystemReady) {
13264                // If we're done calling all the receivers, run the next "boot phase" passed in
13265                // by the SystemServer
13266                if (goingCallback != null) {
13267                    goingCallback.run();
13268                }
13269                return;
13270            }
13271
13272            mLocalDeviceIdleController
13273                    = LocalServices.getService(DeviceIdleController.LocalService.class);
13274
13275            // Make sure we have the current profile info, since it is needed for security checks.
13276            mUserController.onSystemReady();
13277            mRecentTasks.onSystemReadyLocked();
13278            mAppOpsService.systemReady();
13279            mSystemReady = true;
13280        }
13281
13282        ArrayList<ProcessRecord> procsToKill = null;
13283        synchronized(mPidsSelfLocked) {
13284            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
13285                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13286                if (!isAllowedWhileBooting(proc.info)){
13287                    if (procsToKill == null) {
13288                        procsToKill = new ArrayList<ProcessRecord>();
13289                    }
13290                    procsToKill.add(proc);
13291                }
13292            }
13293        }
13294
13295        synchronized(this) {
13296            if (procsToKill != null) {
13297                for (int i=procsToKill.size()-1; i>=0; i--) {
13298                    ProcessRecord proc = procsToKill.get(i);
13299                    Slog.i(TAG, "Removing system update proc: " + proc);
13300                    removeProcessLocked(proc, true, false, "system update done");
13301                }
13302            }
13303
13304            // Now that we have cleaned up any update processes, we
13305            // are ready to start launching real processes and know that
13306            // we won't trample on them any more.
13307            mProcessesReady = true;
13308        }
13309
13310        Slog.i(TAG, "System now ready");
13311        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
13312            SystemClock.uptimeMillis());
13313
13314        synchronized(this) {
13315            // Make sure we have no pre-ready processes sitting around.
13316
13317            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
13318                ResolveInfo ri = mContext.getPackageManager()
13319                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
13320                                STOCK_PM_FLAGS);
13321                CharSequence errorMsg = null;
13322                if (ri != null) {
13323                    ActivityInfo ai = ri.activityInfo;
13324                    ApplicationInfo app = ai.applicationInfo;
13325                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
13326                        mTopAction = Intent.ACTION_FACTORY_TEST;
13327                        mTopData = null;
13328                        mTopComponent = new ComponentName(app.packageName,
13329                                ai.name);
13330                    } else {
13331                        errorMsg = mContext.getResources().getText(
13332                                com.android.internal.R.string.factorytest_not_system);
13333                    }
13334                } else {
13335                    errorMsg = mContext.getResources().getText(
13336                            com.android.internal.R.string.factorytest_no_action);
13337                }
13338                if (errorMsg != null) {
13339                    mTopAction = null;
13340                    mTopData = null;
13341                    mTopComponent = null;
13342                    Message msg = Message.obtain();
13343                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
13344                    msg.getData().putCharSequence("msg", errorMsg);
13345                    mUiHandler.sendMessage(msg);
13346                }
13347            }
13348        }
13349
13350        retrieveSettings();
13351        final int currentUserId;
13352        synchronized (this) {
13353            currentUserId = mUserController.getCurrentUserIdLocked();
13354            readGrantedUriPermissionsLocked();
13355        }
13356
13357        if (goingCallback != null) goingCallback.run();
13358
13359        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
13360                Integer.toString(currentUserId), currentUserId);
13361        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
13362                Integer.toString(currentUserId), currentUserId);
13363        mSystemServiceManager.startUser(currentUserId);
13364
13365        synchronized (this) {
13366            // Only start up encryption-aware persistent apps; once user is
13367            // unlocked we'll come back around and start unaware apps
13368            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
13369
13370            // Start up initial activity.
13371            mBooting = true;
13372            // Enable home activity for system user, so that the system can always boot
13373            if (UserManager.isSplitSystemUser()) {
13374                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
13375                try {
13376                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
13377                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
13378                            UserHandle.USER_SYSTEM);
13379                } catch (RemoteException e) {
13380                    throw e.rethrowAsRuntimeException();
13381                }
13382            }
13383            startHomeActivityLocked(currentUserId, "systemReady");
13384
13385            try {
13386                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
13387                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
13388                            + " data partition or your device will be unstable.");
13389                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
13390                }
13391            } catch (RemoteException e) {
13392            }
13393
13394            if (!Build.isBuildConsistent()) {
13395                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
13396                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
13397            }
13398
13399            long ident = Binder.clearCallingIdentity();
13400            try {
13401                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
13402                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13403                        | Intent.FLAG_RECEIVER_FOREGROUND);
13404                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13405                broadcastIntentLocked(null, null, intent,
13406                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
13407                        null, false, false, MY_PID, Process.SYSTEM_UID,
13408                        currentUserId);
13409                intent = new Intent(Intent.ACTION_USER_STARTING);
13410                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13411                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13412                broadcastIntentLocked(null, null, intent,
13413                        null, new IIntentReceiver.Stub() {
13414                            @Override
13415                            public void performReceive(Intent intent, int resultCode, String data,
13416                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13417                                    throws RemoteException {
13418                            }
13419                        }, 0, null, null,
13420                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13421                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13422            } catch (Throwable t) {
13423                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13424            } finally {
13425                Binder.restoreCallingIdentity(ident);
13426            }
13427            mStackSupervisor.resumeFocusedStackTopActivityLocked();
13428            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13429        }
13430    }
13431
13432    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13433        synchronized (this) {
13434            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13435        }
13436    }
13437
13438    void skipCurrentReceiverLocked(ProcessRecord app) {
13439        for (BroadcastQueue queue : mBroadcastQueues) {
13440            queue.skipCurrentReceiverLocked(app);
13441        }
13442    }
13443
13444    /**
13445     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13446     * The application process will exit immediately after this call returns.
13447     * @param app object of the crashing app, null for the system server
13448     * @param crashInfo describing the exception
13449     */
13450    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
13451        ProcessRecord r = findAppProcess(app, "Crash");
13452        final String processName = app == null ? "system_server"
13453                : (r == null ? "unknown" : r.processName);
13454
13455        handleApplicationCrashInner("crash", r, processName, crashInfo);
13456    }
13457
13458    /* Native crash reporting uses this inner version because it needs to be somewhat
13459     * decoupled from the AM-managed cleanup lifecycle
13460     */
13461    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13462            ApplicationErrorReport.CrashInfo crashInfo) {
13463        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13464                UserHandle.getUserId(Binder.getCallingUid()), processName,
13465                r == null ? -1 : r.info.flags,
13466                crashInfo.exceptionClassName,
13467                crashInfo.exceptionMessage,
13468                crashInfo.throwFileName,
13469                crashInfo.throwLineNumber);
13470
13471        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13472
13473        mAppErrors.crashApplication(r, crashInfo);
13474    }
13475
13476    public void handleApplicationStrictModeViolation(
13477            IBinder app,
13478            int violationMask,
13479            StrictMode.ViolationInfo info) {
13480        ProcessRecord r = findAppProcess(app, "StrictMode");
13481        if (r == null) {
13482            return;
13483        }
13484
13485        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13486            Integer stackFingerprint = info.hashCode();
13487            boolean logIt = true;
13488            synchronized (mAlreadyLoggedViolatedStacks) {
13489                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13490                    logIt = false;
13491                    // TODO: sub-sample into EventLog for these, with
13492                    // the info.durationMillis?  Then we'd get
13493                    // the relative pain numbers, without logging all
13494                    // the stack traces repeatedly.  We'd want to do
13495                    // likewise in the client code, which also does
13496                    // dup suppression, before the Binder call.
13497                } else {
13498                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13499                        mAlreadyLoggedViolatedStacks.clear();
13500                    }
13501                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13502                }
13503            }
13504            if (logIt) {
13505                logStrictModeViolationToDropBox(r, info);
13506            }
13507        }
13508
13509        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13510            AppErrorResult result = new AppErrorResult();
13511            synchronized (this) {
13512                final long origId = Binder.clearCallingIdentity();
13513
13514                Message msg = Message.obtain();
13515                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13516                HashMap<String, Object> data = new HashMap<String, Object>();
13517                data.put("result", result);
13518                data.put("app", r);
13519                data.put("violationMask", violationMask);
13520                data.put("info", info);
13521                msg.obj = data;
13522                mUiHandler.sendMessage(msg);
13523
13524                Binder.restoreCallingIdentity(origId);
13525            }
13526            int res = result.get();
13527            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13528        }
13529    }
13530
13531    // Depending on the policy in effect, there could be a bunch of
13532    // these in quick succession so we try to batch these together to
13533    // minimize disk writes, number of dropbox entries, and maximize
13534    // compression, by having more fewer, larger records.
13535    private void logStrictModeViolationToDropBox(
13536            ProcessRecord process,
13537            StrictMode.ViolationInfo info) {
13538        if (info == null) {
13539            return;
13540        }
13541        final boolean isSystemApp = process == null ||
13542                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13543                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13544        final String processName = process == null ? "unknown" : process.processName;
13545        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13546        final DropBoxManager dbox = (DropBoxManager)
13547                mContext.getSystemService(Context.DROPBOX_SERVICE);
13548
13549        // Exit early if the dropbox isn't configured to accept this report type.
13550        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13551
13552        boolean bufferWasEmpty;
13553        boolean needsFlush;
13554        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13555        synchronized (sb) {
13556            bufferWasEmpty = sb.length() == 0;
13557            appendDropBoxProcessHeaders(process, processName, sb);
13558            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13559            sb.append("System-App: ").append(isSystemApp).append("\n");
13560            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13561            if (info.violationNumThisLoop != 0) {
13562                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13563            }
13564            if (info.numAnimationsRunning != 0) {
13565                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13566            }
13567            if (info.broadcastIntentAction != null) {
13568                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13569            }
13570            if (info.durationMillis != -1) {
13571                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13572            }
13573            if (info.numInstances != -1) {
13574                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13575            }
13576            if (info.tags != null) {
13577                for (String tag : info.tags) {
13578                    sb.append("Span-Tag: ").append(tag).append("\n");
13579                }
13580            }
13581            sb.append("\n");
13582            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13583                sb.append(info.crashInfo.stackTrace);
13584                sb.append("\n");
13585            }
13586            if (info.message != null) {
13587                sb.append(info.message);
13588                sb.append("\n");
13589            }
13590
13591            // Only buffer up to ~64k.  Various logging bits truncate
13592            // things at 128k.
13593            needsFlush = (sb.length() > 64 * 1024);
13594        }
13595
13596        // Flush immediately if the buffer's grown too large, or this
13597        // is a non-system app.  Non-system apps are isolated with a
13598        // different tag & policy and not batched.
13599        //
13600        // Batching is useful during internal testing with
13601        // StrictMode settings turned up high.  Without batching,
13602        // thousands of separate files could be created on boot.
13603        if (!isSystemApp || needsFlush) {
13604            new Thread("Error dump: " + dropboxTag) {
13605                @Override
13606                public void run() {
13607                    String report;
13608                    synchronized (sb) {
13609                        report = sb.toString();
13610                        sb.delete(0, sb.length());
13611                        sb.trimToSize();
13612                    }
13613                    if (report.length() != 0) {
13614                        dbox.addText(dropboxTag, report);
13615                    }
13616                }
13617            }.start();
13618            return;
13619        }
13620
13621        // System app batching:
13622        if (!bufferWasEmpty) {
13623            // An existing dropbox-writing thread is outstanding, so
13624            // we don't need to start it up.  The existing thread will
13625            // catch the buffer appends we just did.
13626            return;
13627        }
13628
13629        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13630        // (After this point, we shouldn't access AMS internal data structures.)
13631        new Thread("Error dump: " + dropboxTag) {
13632            @Override
13633            public void run() {
13634                // 5 second sleep to let stacks arrive and be batched together
13635                try {
13636                    Thread.sleep(5000);  // 5 seconds
13637                } catch (InterruptedException e) {}
13638
13639                String errorReport;
13640                synchronized (mStrictModeBuffer) {
13641                    errorReport = mStrictModeBuffer.toString();
13642                    if (errorReport.length() == 0) {
13643                        return;
13644                    }
13645                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13646                    mStrictModeBuffer.trimToSize();
13647                }
13648                dbox.addText(dropboxTag, errorReport);
13649            }
13650        }.start();
13651    }
13652
13653    /**
13654     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13655     * @param app object of the crashing app, null for the system server
13656     * @param tag reported by the caller
13657     * @param system whether this wtf is coming from the system
13658     * @param crashInfo describing the context of the error
13659     * @return true if the process should exit immediately (WTF is fatal)
13660     */
13661    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13662            final ApplicationErrorReport.CrashInfo crashInfo) {
13663        final int callingUid = Binder.getCallingUid();
13664        final int callingPid = Binder.getCallingPid();
13665
13666        if (system) {
13667            // If this is coming from the system, we could very well have low-level
13668            // system locks held, so we want to do this all asynchronously.  And we
13669            // never want this to become fatal, so there is that too.
13670            mHandler.post(new Runnable() {
13671                @Override public void run() {
13672                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13673                }
13674            });
13675            return false;
13676        }
13677
13678        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13679                crashInfo);
13680
13681        if (r != null && r.pid != Process.myPid() &&
13682                Settings.Global.getInt(mContext.getContentResolver(),
13683                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13684            mAppErrors.crashApplication(r, crashInfo);
13685            return true;
13686        } else {
13687            return false;
13688        }
13689    }
13690
13691    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13692            final ApplicationErrorReport.CrashInfo crashInfo) {
13693        final ProcessRecord r = findAppProcess(app, "WTF");
13694        final String processName = app == null ? "system_server"
13695                : (r == null ? "unknown" : r.processName);
13696
13697        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13698                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13699
13700        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13701
13702        return r;
13703    }
13704
13705    /**
13706     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13707     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13708     */
13709    private ProcessRecord findAppProcess(IBinder app, String reason) {
13710        if (app == null) {
13711            return null;
13712        }
13713
13714        synchronized (this) {
13715            final int NP = mProcessNames.getMap().size();
13716            for (int ip=0; ip<NP; ip++) {
13717                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13718                final int NA = apps.size();
13719                for (int ia=0; ia<NA; ia++) {
13720                    ProcessRecord p = apps.valueAt(ia);
13721                    if (p.thread != null && p.thread.asBinder() == app) {
13722                        return p;
13723                    }
13724                }
13725            }
13726
13727            Slog.w(TAG, "Can't find mystery application for " + reason
13728                    + " from pid=" + Binder.getCallingPid()
13729                    + " uid=" + Binder.getCallingUid() + ": " + app);
13730            return null;
13731        }
13732    }
13733
13734    /**
13735     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13736     * to append various headers to the dropbox log text.
13737     */
13738    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13739            StringBuilder sb) {
13740        // Watchdog thread ends up invoking this function (with
13741        // a null ProcessRecord) to add the stack file to dropbox.
13742        // Do not acquire a lock on this (am) in such cases, as it
13743        // could cause a potential deadlock, if and when watchdog
13744        // is invoked due to unavailability of lock on am and it
13745        // would prevent watchdog from killing system_server.
13746        if (process == null) {
13747            sb.append("Process: ").append(processName).append("\n");
13748            return;
13749        }
13750        // Note: ProcessRecord 'process' is guarded by the service
13751        // instance.  (notably process.pkgList, which could otherwise change
13752        // concurrently during execution of this method)
13753        synchronized (this) {
13754            sb.append("Process: ").append(processName).append("\n");
13755            int flags = process.info.flags;
13756            IPackageManager pm = AppGlobals.getPackageManager();
13757            sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
13758            for (int ip=0; ip<process.pkgList.size(); ip++) {
13759                String pkg = process.pkgList.keyAt(ip);
13760                sb.append("Package: ").append(pkg);
13761                try {
13762                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13763                    if (pi != null) {
13764                        sb.append(" v").append(pi.versionCode);
13765                        if (pi.versionName != null) {
13766                            sb.append(" (").append(pi.versionName).append(")");
13767                        }
13768                    }
13769                } catch (RemoteException e) {
13770                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13771                }
13772                sb.append("\n");
13773            }
13774        }
13775    }
13776
13777    private static String processClass(ProcessRecord process) {
13778        if (process == null || process.pid == MY_PID) {
13779            return "system_server";
13780        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13781            return "system_app";
13782        } else {
13783            return "data_app";
13784        }
13785    }
13786
13787    private volatile long mWtfClusterStart;
13788    private volatile int mWtfClusterCount;
13789
13790    /**
13791     * Write a description of an error (crash, WTF, ANR) to the drop box.
13792     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13793     * @param process which caused the error, null means the system server
13794     * @param activity which triggered the error, null if unknown
13795     * @param parent activity related to the error, null if unknown
13796     * @param subject line related to the error, null if absent
13797     * @param report in long form describing the error, null if absent
13798     * @param dataFile text file to include in the report, null if none
13799     * @param crashInfo giving an application stack trace, null if absent
13800     */
13801    public void addErrorToDropBox(String eventType,
13802            ProcessRecord process, String processName, ActivityRecord activity,
13803            ActivityRecord parent, String subject,
13804            final String report, final File dataFile,
13805            final ApplicationErrorReport.CrashInfo crashInfo) {
13806        // NOTE -- this must never acquire the ActivityManagerService lock,
13807        // otherwise the watchdog may be prevented from resetting the system.
13808
13809        final String dropboxTag = processClass(process) + "_" + eventType;
13810        final DropBoxManager dbox = (DropBoxManager)
13811                mContext.getSystemService(Context.DROPBOX_SERVICE);
13812
13813        // Exit early if the dropbox isn't configured to accept this report type.
13814        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13815
13816        // Rate-limit how often we're willing to do the heavy lifting below to
13817        // collect and record logs; currently 5 logs per 10 second period.
13818        final long now = SystemClock.elapsedRealtime();
13819        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13820            mWtfClusterStart = now;
13821            mWtfClusterCount = 1;
13822        } else {
13823            if (mWtfClusterCount++ >= 5) return;
13824        }
13825
13826        final StringBuilder sb = new StringBuilder(1024);
13827        appendDropBoxProcessHeaders(process, processName, sb);
13828        if (process != null) {
13829            sb.append("Foreground: ")
13830                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13831                    .append("\n");
13832        }
13833        if (activity != null) {
13834            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13835        }
13836        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13837            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13838        }
13839        if (parent != null && parent != activity) {
13840            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13841        }
13842        if (subject != null) {
13843            sb.append("Subject: ").append(subject).append("\n");
13844        }
13845        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13846        if (Debug.isDebuggerConnected()) {
13847            sb.append("Debugger: Connected\n");
13848        }
13849        sb.append("\n");
13850
13851        // Do the rest in a worker thread to avoid blocking the caller on I/O
13852        // (After this point, we shouldn't access AMS internal data structures.)
13853        Thread worker = new Thread("Error dump: " + dropboxTag) {
13854            @Override
13855            public void run() {
13856                if (report != null) {
13857                    sb.append(report);
13858                }
13859
13860                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13861                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13862                int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
13863                        - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
13864
13865                if (dataFile != null && maxDataFileSize > 0) {
13866                    try {
13867                        sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
13868                                    "\n\n[[TRUNCATED]]"));
13869                    } catch (IOException e) {
13870                        Slog.e(TAG, "Error reading " + dataFile, e);
13871                    }
13872                }
13873                if (crashInfo != null && crashInfo.stackTrace != null) {
13874                    sb.append(crashInfo.stackTrace);
13875                }
13876
13877                if (lines > 0) {
13878                    sb.append("\n");
13879
13880                    // Merge several logcat streams, and take the last N lines
13881                    InputStreamReader input = null;
13882                    try {
13883                        java.lang.Process logcat = new ProcessBuilder(
13884                                "/system/bin/timeout", "-k", "15s", "10s",
13885                                "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
13886                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13887                                        .redirectErrorStream(true).start();
13888
13889                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13890                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13891                        input = new InputStreamReader(logcat.getInputStream());
13892
13893                        int num;
13894                        char[] buf = new char[8192];
13895                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13896                    } catch (IOException e) {
13897                        Slog.e(TAG, "Error running logcat", e);
13898                    } finally {
13899                        if (input != null) try { input.close(); } catch (IOException e) {}
13900                    }
13901                }
13902
13903                dbox.addText(dropboxTag, sb.toString());
13904            }
13905        };
13906
13907        if (process == null) {
13908            // If process is null, we are being called from some internal code
13909            // and may be about to die -- run this synchronously.
13910            worker.run();
13911        } else {
13912            worker.start();
13913        }
13914    }
13915
13916    @Override
13917    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13918        enforceNotIsolatedCaller("getProcessesInErrorState");
13919        // assume our apps are happy - lazy create the list
13920        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13921
13922        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13923                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13924        int userId = UserHandle.getUserId(Binder.getCallingUid());
13925
13926        synchronized (this) {
13927
13928            // iterate across all processes
13929            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13930                ProcessRecord app = mLruProcesses.get(i);
13931                if (!allUsers && app.userId != userId) {
13932                    continue;
13933                }
13934                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13935                    // This one's in trouble, so we'll generate a report for it
13936                    // crashes are higher priority (in case there's a crash *and* an anr)
13937                    ActivityManager.ProcessErrorStateInfo report = null;
13938                    if (app.crashing) {
13939                        report = app.crashingReport;
13940                    } else if (app.notResponding) {
13941                        report = app.notRespondingReport;
13942                    }
13943
13944                    if (report != null) {
13945                        if (errList == null) {
13946                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13947                        }
13948                        errList.add(report);
13949                    } else {
13950                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13951                                " crashing = " + app.crashing +
13952                                " notResponding = " + app.notResponding);
13953                    }
13954                }
13955            }
13956        }
13957
13958        return errList;
13959    }
13960
13961    static int procStateToImportance(int procState, int memAdj,
13962            ActivityManager.RunningAppProcessInfo currApp) {
13963        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13964        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13965            currApp.lru = memAdj;
13966        } else {
13967            currApp.lru = 0;
13968        }
13969        return imp;
13970    }
13971
13972    private void fillInProcMemInfo(ProcessRecord app,
13973            ActivityManager.RunningAppProcessInfo outInfo) {
13974        outInfo.pid = app.pid;
13975        outInfo.uid = app.info.uid;
13976        if (mHeavyWeightProcess == app) {
13977            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13978        }
13979        if (app.persistent) {
13980            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13981        }
13982        if (app.activities.size() > 0) {
13983            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13984        }
13985        outInfo.lastTrimLevel = app.trimMemoryLevel;
13986        int adj = app.curAdj;
13987        int procState = app.curProcState;
13988        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13989        outInfo.importanceReasonCode = app.adjTypeCode;
13990        outInfo.processState = app.curProcState;
13991    }
13992
13993    @Override
13994    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13995        enforceNotIsolatedCaller("getRunningAppProcesses");
13996
13997        final int callingUid = Binder.getCallingUid();
13998
13999        // Lazy instantiation of list
14000        List<ActivityManager.RunningAppProcessInfo> runList = null;
14001        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14002                callingUid) == PackageManager.PERMISSION_GRANTED;
14003        final int userId = UserHandle.getUserId(callingUid);
14004        final boolean allUids = isGetTasksAllowed(
14005                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
14006
14007        synchronized (this) {
14008            // Iterate across all processes
14009            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14010                ProcessRecord app = mLruProcesses.get(i);
14011                if ((!allUsers && app.userId != userId)
14012                        || (!allUids && app.uid != callingUid)) {
14013                    continue;
14014                }
14015                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
14016                    // Generate process state info for running application
14017                    ActivityManager.RunningAppProcessInfo currApp =
14018                        new ActivityManager.RunningAppProcessInfo(app.processName,
14019                                app.pid, app.getPackageList());
14020                    fillInProcMemInfo(app, currApp);
14021                    if (app.adjSource instanceof ProcessRecord) {
14022                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
14023                        currApp.importanceReasonImportance =
14024                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
14025                                        app.adjSourceProcState);
14026                    } else if (app.adjSource instanceof ActivityRecord) {
14027                        ActivityRecord r = (ActivityRecord)app.adjSource;
14028                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
14029                    }
14030                    if (app.adjTarget instanceof ComponentName) {
14031                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
14032                    }
14033                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
14034                    //        + " lru=" + currApp.lru);
14035                    if (runList == null) {
14036                        runList = new ArrayList<>();
14037                    }
14038                    runList.add(currApp);
14039                }
14040            }
14041        }
14042        return runList;
14043    }
14044
14045    @Override
14046    public List<ApplicationInfo> getRunningExternalApplications() {
14047        enforceNotIsolatedCaller("getRunningExternalApplications");
14048        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
14049        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
14050        if (runningApps != null && runningApps.size() > 0) {
14051            Set<String> extList = new HashSet<String>();
14052            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
14053                if (app.pkgList != null) {
14054                    for (String pkg : app.pkgList) {
14055                        extList.add(pkg);
14056                    }
14057                }
14058            }
14059            IPackageManager pm = AppGlobals.getPackageManager();
14060            for (String pkg : extList) {
14061                try {
14062                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
14063                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
14064                        retList.add(info);
14065                    }
14066                } catch (RemoteException e) {
14067                }
14068            }
14069        }
14070        return retList;
14071    }
14072
14073    @Override
14074    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
14075        enforceNotIsolatedCaller("getMyMemoryState");
14076        synchronized (this) {
14077            ProcessRecord proc;
14078            synchronized (mPidsSelfLocked) {
14079                proc = mPidsSelfLocked.get(Binder.getCallingPid());
14080            }
14081            fillInProcMemInfo(proc, outInfo);
14082        }
14083    }
14084
14085    @Override
14086    public int getMemoryTrimLevel() {
14087        enforceNotIsolatedCaller("getMyMemoryState");
14088        synchronized (this) {
14089            return mLastMemoryLevel;
14090        }
14091    }
14092
14093    @Override
14094    public void onShellCommand(FileDescriptor in, FileDescriptor out,
14095            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
14096        (new ActivityManagerShellCommand(this, false)).exec(
14097                this, in, out, err, args, resultReceiver);
14098    }
14099
14100    @Override
14101    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
14102        if (checkCallingPermission(android.Manifest.permission.DUMP)
14103                != PackageManager.PERMISSION_GRANTED) {
14104            pw.println("Permission Denial: can't dump ActivityManager from from pid="
14105                    + Binder.getCallingPid()
14106                    + ", uid=" + Binder.getCallingUid()
14107                    + " without permission "
14108                    + android.Manifest.permission.DUMP);
14109            return;
14110        }
14111
14112        boolean dumpAll = false;
14113        boolean dumpClient = false;
14114        boolean dumpCheckin = false;
14115        boolean dumpCheckinFormat = false;
14116        String dumpPackage = null;
14117
14118        int opti = 0;
14119        while (opti < args.length) {
14120            String opt = args[opti];
14121            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14122                break;
14123            }
14124            opti++;
14125            if ("-a".equals(opt)) {
14126                dumpAll = true;
14127            } else if ("-c".equals(opt)) {
14128                dumpClient = true;
14129            } else if ("-p".equals(opt)) {
14130                if (opti < args.length) {
14131                    dumpPackage = args[opti];
14132                    opti++;
14133                } else {
14134                    pw.println("Error: -p option requires package argument");
14135                    return;
14136                }
14137                dumpClient = true;
14138            } else if ("--checkin".equals(opt)) {
14139                dumpCheckin = dumpCheckinFormat = true;
14140            } else if ("-C".equals(opt)) {
14141                dumpCheckinFormat = true;
14142            } else if ("-h".equals(opt)) {
14143                ActivityManagerShellCommand.dumpHelp(pw, true);
14144                return;
14145            } else {
14146                pw.println("Unknown argument: " + opt + "; use -h for help");
14147            }
14148        }
14149
14150        long origId = Binder.clearCallingIdentity();
14151        boolean more = false;
14152        // Is the caller requesting to dump a particular piece of data?
14153        if (opti < args.length) {
14154            String cmd = args[opti];
14155            opti++;
14156            if ("activities".equals(cmd) || "a".equals(cmd)) {
14157                synchronized (this) {
14158                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14159                }
14160            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
14161                synchronized (this) {
14162                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
14163                }
14164            } else if ("broadcasts".equals(cmd) || "b".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                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
14179                }
14180            } else if ("broadcast-stats".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                    if (dumpCheckinFormat) {
14195                        dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
14196                                dumpPackage);
14197                    } else {
14198                        dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
14199                    }
14200                }
14201            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
14202                String[] newArgs;
14203                String name;
14204                if (opti >= args.length) {
14205                    name = null;
14206                    newArgs = EMPTY_STRING_ARRAY;
14207                } else {
14208                    dumpPackage = args[opti];
14209                    opti++;
14210                    newArgs = new String[args.length - opti];
14211                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14212                            args.length - opti);
14213                }
14214                synchronized (this) {
14215                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
14216                }
14217            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
14218                String[] newArgs;
14219                String name;
14220                if (opti >= args.length) {
14221                    name = null;
14222                    newArgs = EMPTY_STRING_ARRAY;
14223                } else {
14224                    dumpPackage = args[opti];
14225                    opti++;
14226                    newArgs = new String[args.length - opti];
14227                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14228                            args.length - opti);
14229                }
14230                synchronized (this) {
14231                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
14232                }
14233            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
14234                synchronized (this) {
14235                    dumpOomLocked(fd, pw, args, opti, true);
14236                }
14237            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
14238                synchronized (this) {
14239                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
14240                }
14241            } else if ("provider".equals(cmd)) {
14242                String[] newArgs;
14243                String name;
14244                if (opti >= args.length) {
14245                    name = null;
14246                    newArgs = EMPTY_STRING_ARRAY;
14247                } else {
14248                    name = args[opti];
14249                    opti++;
14250                    newArgs = new String[args.length - opti];
14251                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14252                }
14253                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
14254                    pw.println("No providers match: " + name);
14255                    pw.println("Use -h for help.");
14256                }
14257            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
14258                synchronized (this) {
14259                    dumpProvidersLocked(fd, pw, args, opti, true, null);
14260                }
14261            } else if ("service".equals(cmd)) {
14262                String[] newArgs;
14263                String name;
14264                if (opti >= args.length) {
14265                    name = null;
14266                    newArgs = EMPTY_STRING_ARRAY;
14267                } else {
14268                    name = args[opti];
14269                    opti++;
14270                    newArgs = new String[args.length - opti];
14271                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14272                            args.length - opti);
14273                }
14274                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
14275                    pw.println("No services match: " + name);
14276                    pw.println("Use -h for help.");
14277                }
14278            } else if ("package".equals(cmd)) {
14279                String[] newArgs;
14280                if (opti >= args.length) {
14281                    pw.println("package: no package name specified");
14282                    pw.println("Use -h for help.");
14283                } else {
14284                    dumpPackage = args[opti];
14285                    opti++;
14286                    newArgs = new String[args.length - opti];
14287                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14288                            args.length - opti);
14289                    args = newArgs;
14290                    opti = 0;
14291                    more = true;
14292                }
14293            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
14294                synchronized (this) {
14295                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14296                }
14297            } else if ("services".equals(cmd) || "s".equals(cmd)) {
14298                if (dumpClient) {
14299                    ActiveServices.ServiceDumper dumper;
14300                    synchronized (this) {
14301                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14302                                dumpPackage);
14303                    }
14304                    dumper.dumpWithClient();
14305                } else {
14306                    synchronized (this) {
14307                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14308                                dumpPackage).dumpLocked();
14309                    }
14310                }
14311            } else if ("locks".equals(cmd)) {
14312                LockGuard.dump(fd, pw, args);
14313            } else {
14314                // Dumping a single activity?
14315                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
14316                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
14317                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
14318                    if (res < 0) {
14319                        pw.println("Bad activity command, or no activities match: " + cmd);
14320                        pw.println("Use -h for help.");
14321                    }
14322                }
14323            }
14324            if (!more) {
14325                Binder.restoreCallingIdentity(origId);
14326                return;
14327            }
14328        }
14329
14330        // No piece of data specified, dump everything.
14331        if (dumpCheckinFormat) {
14332            dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
14333        } else if (dumpClient) {
14334            ActiveServices.ServiceDumper sdumper;
14335            synchronized (this) {
14336                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14337                pw.println();
14338                if (dumpAll) {
14339                    pw.println("-------------------------------------------------------------------------------");
14340                }
14341                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14342                pw.println();
14343                if (dumpAll) {
14344                    pw.println("-------------------------------------------------------------------------------");
14345                }
14346                if (dumpAll || dumpPackage != null) {
14347                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14348                    pw.println();
14349                    if (dumpAll) {
14350                        pw.println("-------------------------------------------------------------------------------");
14351                    }
14352                }
14353                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14354                pw.println();
14355                if (dumpAll) {
14356                    pw.println("-------------------------------------------------------------------------------");
14357                }
14358                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14359                pw.println();
14360                if (dumpAll) {
14361                    pw.println("-------------------------------------------------------------------------------");
14362                }
14363                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
14364                        dumpPackage);
14365            }
14366            sdumper.dumpWithClient();
14367            pw.println();
14368            synchronized (this) {
14369                if (dumpAll) {
14370                    pw.println("-------------------------------------------------------------------------------");
14371                }
14372                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14373                pw.println();
14374                if (dumpAll) {
14375                    pw.println("-------------------------------------------------------------------------------");
14376                }
14377                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14378                if (mAssociations.size() > 0) {
14379                    pw.println();
14380                    if (dumpAll) {
14381                        pw.println("-------------------------------------------------------------------------------");
14382                    }
14383                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14384                }
14385                pw.println();
14386                if (dumpAll) {
14387                    pw.println("-------------------------------------------------------------------------------");
14388                }
14389                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14390            }
14391
14392        } else {
14393            synchronized (this) {
14394                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14395                pw.println();
14396                if (dumpAll) {
14397                    pw.println("-------------------------------------------------------------------------------");
14398                }
14399                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14400                pw.println();
14401                if (dumpAll) {
14402                    pw.println("-------------------------------------------------------------------------------");
14403                }
14404                if (dumpAll || dumpPackage != null) {
14405                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14406                    pw.println();
14407                    if (dumpAll) {
14408                        pw.println("-------------------------------------------------------------------------------");
14409                    }
14410                }
14411                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14412                pw.println();
14413                if (dumpAll) {
14414                    pw.println("-------------------------------------------------------------------------------");
14415                }
14416                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14417                pw.println();
14418                if (dumpAll) {
14419                    pw.println("-------------------------------------------------------------------------------");
14420                }
14421                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
14422                        .dumpLocked();
14423                pw.println();
14424                if (dumpAll) {
14425                    pw.println("-------------------------------------------------------------------------------");
14426                }
14427                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14428                pw.println();
14429                if (dumpAll) {
14430                    pw.println("-------------------------------------------------------------------------------");
14431                }
14432                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14433                if (mAssociations.size() > 0) {
14434                    pw.println();
14435                    if (dumpAll) {
14436                        pw.println("-------------------------------------------------------------------------------");
14437                    }
14438                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14439                }
14440                pw.println();
14441                if (dumpAll) {
14442                    pw.println("-------------------------------------------------------------------------------");
14443                }
14444                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14445            }
14446        }
14447        Binder.restoreCallingIdentity(origId);
14448    }
14449
14450    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14451            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14452        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
14453
14454        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
14455                dumpPackage);
14456        boolean needSep = printedAnything;
14457
14458        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
14459                dumpPackage, needSep, "  mFocusedActivity: ");
14460        if (printed) {
14461            printedAnything = true;
14462            needSep = false;
14463        }
14464
14465        if (dumpPackage == null) {
14466            if (needSep) {
14467                pw.println();
14468            }
14469            needSep = true;
14470            printedAnything = true;
14471            mStackSupervisor.dump(pw, "  ");
14472        }
14473
14474        if (!printedAnything) {
14475            pw.println("  (nothing)");
14476        }
14477    }
14478
14479    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14480            int opti, boolean dumpAll, String dumpPackage) {
14481        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14482
14483        boolean printedAnything = false;
14484
14485        if (mRecentTasks != null && mRecentTasks.size() > 0) {
14486            boolean printedHeader = false;
14487
14488            final int N = mRecentTasks.size();
14489            for (int i=0; i<N; i++) {
14490                TaskRecord tr = mRecentTasks.get(i);
14491                if (dumpPackage != null) {
14492                    if (tr.realActivity == null ||
14493                            !dumpPackage.equals(tr.realActivity)) {
14494                        continue;
14495                    }
14496                }
14497                if (!printedHeader) {
14498                    pw.println("  Recent tasks:");
14499                    printedHeader = true;
14500                    printedAnything = true;
14501                }
14502                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
14503                        pw.println(tr);
14504                if (dumpAll) {
14505                    mRecentTasks.get(i).dump(pw, "    ");
14506                }
14507            }
14508        }
14509
14510        if (!printedAnything) {
14511            pw.println("  (nothing)");
14512        }
14513    }
14514
14515    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14516            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14517        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14518
14519        int dumpUid = 0;
14520        if (dumpPackage != null) {
14521            IPackageManager pm = AppGlobals.getPackageManager();
14522            try {
14523                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
14524            } catch (RemoteException e) {
14525            }
14526        }
14527
14528        boolean printedAnything = false;
14529
14530        final long now = SystemClock.uptimeMillis();
14531
14532        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14533            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14534                    = mAssociations.valueAt(i1);
14535            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14536                SparseArray<ArrayMap<String, Association>> sourceUids
14537                        = targetComponents.valueAt(i2);
14538                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14539                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14540                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14541                        Association ass = sourceProcesses.valueAt(i4);
14542                        if (dumpPackage != null) {
14543                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14544                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14545                                continue;
14546                            }
14547                        }
14548                        printedAnything = true;
14549                        pw.print("  ");
14550                        pw.print(ass.mTargetProcess);
14551                        pw.print("/");
14552                        UserHandle.formatUid(pw, ass.mTargetUid);
14553                        pw.print(" <- ");
14554                        pw.print(ass.mSourceProcess);
14555                        pw.print("/");
14556                        UserHandle.formatUid(pw, ass.mSourceUid);
14557                        pw.println();
14558                        pw.print("    via ");
14559                        pw.print(ass.mTargetComponent.flattenToShortString());
14560                        pw.println();
14561                        pw.print("    ");
14562                        long dur = ass.mTime;
14563                        if (ass.mNesting > 0) {
14564                            dur += now - ass.mStartTime;
14565                        }
14566                        TimeUtils.formatDuration(dur, pw);
14567                        pw.print(" (");
14568                        pw.print(ass.mCount);
14569                        pw.print(" times)");
14570                        pw.print("  ");
14571                        for (int i=0; i<ass.mStateTimes.length; i++) {
14572                            long amt = ass.mStateTimes[i];
14573                            if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14574                                amt += now - ass.mLastStateUptime;
14575                            }
14576                            if (amt != 0) {
14577                                pw.print(" ");
14578                                pw.print(ProcessList.makeProcStateString(
14579                                            i + ActivityManager.MIN_PROCESS_STATE));
14580                                pw.print("=");
14581                                TimeUtils.formatDuration(amt, pw);
14582                                if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14583                                    pw.print("*");
14584                                }
14585                            }
14586                        }
14587                        pw.println();
14588                        if (ass.mNesting > 0) {
14589                            pw.print("    Currently active: ");
14590                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
14591                            pw.println();
14592                        }
14593                    }
14594                }
14595            }
14596
14597        }
14598
14599        if (!printedAnything) {
14600            pw.println("  (nothing)");
14601        }
14602    }
14603
14604    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14605            String header, boolean needSep) {
14606        boolean printed = false;
14607        int whichAppId = -1;
14608        if (dumpPackage != null) {
14609            try {
14610                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14611                        dumpPackage, 0);
14612                whichAppId = UserHandle.getAppId(info.uid);
14613            } catch (NameNotFoundException e) {
14614                e.printStackTrace();
14615            }
14616        }
14617        for (int i=0; i<uids.size(); i++) {
14618            UidRecord uidRec = uids.valueAt(i);
14619            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14620                continue;
14621            }
14622            if (!printed) {
14623                printed = true;
14624                if (needSep) {
14625                    pw.println();
14626                }
14627                pw.print("  ");
14628                pw.println(header);
14629                needSep = true;
14630            }
14631            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14632            pw.print(": "); pw.println(uidRec);
14633        }
14634        return printed;
14635    }
14636
14637    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14638            int opti, boolean dumpAll, String dumpPackage) {
14639        boolean needSep = false;
14640        boolean printedAnything = false;
14641        int numPers = 0;
14642
14643        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14644
14645        if (dumpAll) {
14646            final int NP = mProcessNames.getMap().size();
14647            for (int ip=0; ip<NP; ip++) {
14648                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14649                final int NA = procs.size();
14650                for (int ia=0; ia<NA; ia++) {
14651                    ProcessRecord r = procs.valueAt(ia);
14652                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14653                        continue;
14654                    }
14655                    if (!needSep) {
14656                        pw.println("  All known processes:");
14657                        needSep = true;
14658                        printedAnything = true;
14659                    }
14660                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14661                        pw.print(" UID "); pw.print(procs.keyAt(ia));
14662                        pw.print(" "); pw.println(r);
14663                    r.dump(pw, "    ");
14664                    if (r.persistent) {
14665                        numPers++;
14666                    }
14667                }
14668            }
14669        }
14670
14671        if (mIsolatedProcesses.size() > 0) {
14672            boolean printed = false;
14673            for (int i=0; i<mIsolatedProcesses.size(); i++) {
14674                ProcessRecord r = mIsolatedProcesses.valueAt(i);
14675                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14676                    continue;
14677                }
14678                if (!printed) {
14679                    if (needSep) {
14680                        pw.println();
14681                    }
14682                    pw.println("  Isolated process list (sorted by uid):");
14683                    printedAnything = true;
14684                    printed = true;
14685                    needSep = true;
14686                }
14687                pw.println(String.format("%sIsolated #%2d: %s",
14688                        "    ", i, r.toString()));
14689            }
14690        }
14691
14692        if (mActiveUids.size() > 0) {
14693            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14694                printedAnything = needSep = true;
14695            }
14696        }
14697        if (mValidateUids.size() > 0) {
14698            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14699                printedAnything = needSep = true;
14700            }
14701        }
14702
14703        if (mLruProcesses.size() > 0) {
14704            if (needSep) {
14705                pw.println();
14706            }
14707            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14708                    pw.print(" total, non-act at ");
14709                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14710                    pw.print(", non-svc at ");
14711                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14712                    pw.println("):");
14713            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14714            needSep = true;
14715            printedAnything = true;
14716        }
14717
14718        if (dumpAll || dumpPackage != null) {
14719            synchronized (mPidsSelfLocked) {
14720                boolean printed = false;
14721                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14722                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14723                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14724                        continue;
14725                    }
14726                    if (!printed) {
14727                        if (needSep) pw.println();
14728                        needSep = true;
14729                        pw.println("  PID mappings:");
14730                        printed = true;
14731                        printedAnything = true;
14732                    }
14733                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14734                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14735                }
14736            }
14737        }
14738
14739        if (mForegroundProcesses.size() > 0) {
14740            synchronized (mPidsSelfLocked) {
14741                boolean printed = false;
14742                for (int i=0; i<mForegroundProcesses.size(); i++) {
14743                    ProcessRecord r = mPidsSelfLocked.get(
14744                            mForegroundProcesses.valueAt(i).pid);
14745                    if (dumpPackage != null && (r == null
14746                            || !r.pkgList.containsKey(dumpPackage))) {
14747                        continue;
14748                    }
14749                    if (!printed) {
14750                        if (needSep) pw.println();
14751                        needSep = true;
14752                        pw.println("  Foreground Processes:");
14753                        printed = true;
14754                        printedAnything = true;
14755                    }
14756                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14757                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14758                }
14759            }
14760        }
14761
14762        if (mPersistentStartingProcesses.size() > 0) {
14763            if (needSep) pw.println();
14764            needSep = true;
14765            printedAnything = true;
14766            pw.println("  Persisent processes that are starting:");
14767            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14768                    "Starting Norm", "Restarting PERS", dumpPackage);
14769        }
14770
14771        if (mRemovedProcesses.size() > 0) {
14772            if (needSep) pw.println();
14773            needSep = true;
14774            printedAnything = true;
14775            pw.println("  Processes that are being removed:");
14776            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14777                    "Removed Norm", "Removed PERS", dumpPackage);
14778        }
14779
14780        if (mProcessesOnHold.size() > 0) {
14781            if (needSep) pw.println();
14782            needSep = true;
14783            printedAnything = true;
14784            pw.println("  Processes that are on old until the system is ready:");
14785            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14786                    "OnHold Norm", "OnHold PERS", dumpPackage);
14787        }
14788
14789        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14790
14791        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14792        if (needSep) {
14793            printedAnything = true;
14794        }
14795
14796        if (dumpPackage == null) {
14797            pw.println();
14798            needSep = false;
14799            mUserController.dump(pw, dumpAll);
14800        }
14801        if (mHomeProcess != null && (dumpPackage == null
14802                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14803            if (needSep) {
14804                pw.println();
14805                needSep = false;
14806            }
14807            pw.println("  mHomeProcess: " + mHomeProcess);
14808        }
14809        if (mPreviousProcess != null && (dumpPackage == null
14810                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14811            if (needSep) {
14812                pw.println();
14813                needSep = false;
14814            }
14815            pw.println("  mPreviousProcess: " + mPreviousProcess);
14816        }
14817        if (dumpAll) {
14818            StringBuilder sb = new StringBuilder(128);
14819            sb.append("  mPreviousProcessVisibleTime: ");
14820            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14821            pw.println(sb);
14822        }
14823        if (mHeavyWeightProcess != null && (dumpPackage == null
14824                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14825            if (needSep) {
14826                pw.println();
14827                needSep = false;
14828            }
14829            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14830        }
14831        if (dumpPackage == null) {
14832            pw.println("  mConfiguration: " + mConfiguration);
14833        }
14834        if (dumpAll) {
14835            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14836            if (mCompatModePackages.getPackages().size() > 0) {
14837                boolean printed = false;
14838                for (Map.Entry<String, Integer> entry
14839                        : mCompatModePackages.getPackages().entrySet()) {
14840                    String pkg = entry.getKey();
14841                    int mode = entry.getValue();
14842                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14843                        continue;
14844                    }
14845                    if (!printed) {
14846                        pw.println("  mScreenCompatPackages:");
14847                        printed = true;
14848                    }
14849                    pw.print("    "); pw.print(pkg); pw.print(": ");
14850                            pw.print(mode); pw.println();
14851                }
14852            }
14853        }
14854        if (dumpPackage == null) {
14855            pw.println("  mWakefulness="
14856                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14857            pw.println("  mSleepTokens=" + mSleepTokens);
14858            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14859                    + lockScreenShownToString());
14860            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14861            if (mRunningVoice != null) {
14862                pw.println("  mRunningVoice=" + mRunningVoice);
14863                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14864            }
14865        }
14866        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14867                || mOrigWaitForDebugger) {
14868            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14869                    || dumpPackage.equals(mOrigDebugApp)) {
14870                if (needSep) {
14871                    pw.println();
14872                    needSep = false;
14873                }
14874                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14875                        + " mDebugTransient=" + mDebugTransient
14876                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14877            }
14878        }
14879        if (mCurAppTimeTracker != null) {
14880            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14881        }
14882        if (mMemWatchProcesses.getMap().size() > 0) {
14883            pw.println("  Mem watch processes:");
14884            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14885                    = mMemWatchProcesses.getMap();
14886            for (int i=0; i<procs.size(); i++) {
14887                final String proc = procs.keyAt(i);
14888                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14889                for (int j=0; j<uids.size(); j++) {
14890                    if (needSep) {
14891                        pw.println();
14892                        needSep = false;
14893                    }
14894                    StringBuilder sb = new StringBuilder();
14895                    sb.append("    ").append(proc).append('/');
14896                    UserHandle.formatUid(sb, uids.keyAt(j));
14897                    Pair<Long, String> val = uids.valueAt(j);
14898                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14899                    if (val.second != null) {
14900                        sb.append(", report to ").append(val.second);
14901                    }
14902                    pw.println(sb.toString());
14903                }
14904            }
14905            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14906            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14907            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14908                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14909        }
14910        if (mTrackAllocationApp != null) {
14911            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14912                if (needSep) {
14913                    pw.println();
14914                    needSep = false;
14915                }
14916                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14917            }
14918        }
14919        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14920                || mProfileFd != null) {
14921            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14922                if (needSep) {
14923                    pw.println();
14924                    needSep = false;
14925                }
14926                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14927                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14928                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14929                        + mAutoStopProfiler + " mStreamingOutput=" + mStreamingOutput);
14930                pw.println("  mProfileType=" + mProfileType);
14931            }
14932        }
14933        if (mNativeDebuggingApp != null) {
14934            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14935                if (needSep) {
14936                    pw.println();
14937                    needSep = false;
14938                }
14939                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14940            }
14941        }
14942        if (dumpPackage == null) {
14943            if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14944                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14945                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14946            }
14947            if (mController != null) {
14948                pw.println("  mController=" + mController
14949                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14950            }
14951            if (dumpAll) {
14952                pw.println("  Total persistent processes: " + numPers);
14953                pw.println("  mProcessesReady=" + mProcessesReady
14954                        + " mSystemReady=" + mSystemReady
14955                        + " mBooted=" + mBooted
14956                        + " mFactoryTest=" + mFactoryTest);
14957                pw.println("  mBooting=" + mBooting
14958                        + " mCallFinishBooting=" + mCallFinishBooting
14959                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14960                pw.print("  mLastPowerCheckRealtime=");
14961                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14962                        pw.println("");
14963                pw.print("  mLastPowerCheckUptime=");
14964                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14965                        pw.println("");
14966                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14967                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14968                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14969                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14970                        + " (" + mLruProcesses.size() + " total)"
14971                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14972                        + " mNumServiceProcs=" + mNumServiceProcs
14973                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14974                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14975                        + " mLastMemoryLevel=" + mLastMemoryLevel
14976                        + " mLastNumProcesses=" + mLastNumProcesses);
14977                long now = SystemClock.uptimeMillis();
14978                pw.print("  mLastIdleTime=");
14979                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14980                        pw.print(" mLowRamSinceLastIdle=");
14981                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14982                        pw.println();
14983            }
14984        }
14985
14986        if (!printedAnything) {
14987            pw.println("  (nothing)");
14988        }
14989    }
14990
14991    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14992            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14993        if (mProcessesToGc.size() > 0) {
14994            boolean printed = false;
14995            long now = SystemClock.uptimeMillis();
14996            for (int i=0; i<mProcessesToGc.size(); i++) {
14997                ProcessRecord proc = mProcessesToGc.get(i);
14998                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14999                    continue;
15000                }
15001                if (!printed) {
15002                    if (needSep) pw.println();
15003                    needSep = true;
15004                    pw.println("  Processes that are waiting to GC:");
15005                    printed = true;
15006                }
15007                pw.print("    Process "); pw.println(proc);
15008                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
15009                        pw.print(", last gced=");
15010                        pw.print(now-proc.lastRequestedGc);
15011                        pw.print(" ms ago, last lowMem=");
15012                        pw.print(now-proc.lastLowMemory);
15013                        pw.println(" ms ago");
15014
15015            }
15016        }
15017        return needSep;
15018    }
15019
15020    void printOomLevel(PrintWriter pw, String name, int adj) {
15021        pw.print("    ");
15022        if (adj >= 0) {
15023            pw.print(' ');
15024            if (adj < 10) pw.print(' ');
15025        } else {
15026            if (adj > -10) pw.print(' ');
15027        }
15028        pw.print(adj);
15029        pw.print(": ");
15030        pw.print(name);
15031        pw.print(" (");
15032        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
15033        pw.println(")");
15034    }
15035
15036    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15037            int opti, boolean dumpAll) {
15038        boolean needSep = false;
15039
15040        if (mLruProcesses.size() > 0) {
15041            if (needSep) pw.println();
15042            needSep = true;
15043            pw.println("  OOM levels:");
15044            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
15045            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
15046            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
15047            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
15048            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
15049            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
15050            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
15051            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
15052            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
15053            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
15054            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
15055            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
15056            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
15057            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
15058
15059            if (needSep) pw.println();
15060            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
15061                    pw.print(" total, non-act at ");
15062                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15063                    pw.print(", non-svc at ");
15064                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15065                    pw.println("):");
15066            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
15067            needSep = true;
15068        }
15069
15070        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
15071
15072        pw.println();
15073        pw.println("  mHomeProcess: " + mHomeProcess);
15074        pw.println("  mPreviousProcess: " + mPreviousProcess);
15075        if (mHeavyWeightProcess != null) {
15076            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
15077        }
15078
15079        return true;
15080    }
15081
15082    /**
15083     * There are three ways to call this:
15084     *  - no provider specified: dump all the providers
15085     *  - a flattened component name that matched an existing provider was specified as the
15086     *    first arg: dump that one provider
15087     *  - the first arg isn't the flattened component name of an existing provider:
15088     *    dump all providers whose component contains the first arg as a substring
15089     */
15090    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15091            int opti, boolean dumpAll) {
15092        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
15093    }
15094
15095    static class ItemMatcher {
15096        ArrayList<ComponentName> components;
15097        ArrayList<String> strings;
15098        ArrayList<Integer> objects;
15099        boolean all;
15100
15101        ItemMatcher() {
15102            all = true;
15103        }
15104
15105        void build(String name) {
15106            ComponentName componentName = ComponentName.unflattenFromString(name);
15107            if (componentName != null) {
15108                if (components == null) {
15109                    components = new ArrayList<ComponentName>();
15110                }
15111                components.add(componentName);
15112                all = false;
15113            } else {
15114                int objectId = 0;
15115                // Not a '/' separated full component name; maybe an object ID?
15116                try {
15117                    objectId = Integer.parseInt(name, 16);
15118                    if (objects == null) {
15119                        objects = new ArrayList<Integer>();
15120                    }
15121                    objects.add(objectId);
15122                    all = false;
15123                } catch (RuntimeException e) {
15124                    // Not an integer; just do string match.
15125                    if (strings == null) {
15126                        strings = new ArrayList<String>();
15127                    }
15128                    strings.add(name);
15129                    all = false;
15130                }
15131            }
15132        }
15133
15134        int build(String[] args, int opti) {
15135            for (; opti<args.length; opti++) {
15136                String name = args[opti];
15137                if ("--".equals(name)) {
15138                    return opti+1;
15139                }
15140                build(name);
15141            }
15142            return opti;
15143        }
15144
15145        boolean match(Object object, ComponentName comp) {
15146            if (all) {
15147                return true;
15148            }
15149            if (components != null) {
15150                for (int i=0; i<components.size(); i++) {
15151                    if (components.get(i).equals(comp)) {
15152                        return true;
15153                    }
15154                }
15155            }
15156            if (objects != null) {
15157                for (int i=0; i<objects.size(); i++) {
15158                    if (System.identityHashCode(object) == objects.get(i)) {
15159                        return true;
15160                    }
15161                }
15162            }
15163            if (strings != null) {
15164                String flat = comp.flattenToString();
15165                for (int i=0; i<strings.size(); i++) {
15166                    if (flat.contains(strings.get(i))) {
15167                        return true;
15168                    }
15169                }
15170            }
15171            return false;
15172        }
15173    }
15174
15175    /**
15176     * There are three things that cmd can be:
15177     *  - a flattened component name that matches an existing activity
15178     *  - the cmd arg isn't the flattened component name of an existing activity:
15179     *    dump all activity whose component contains the cmd as a substring
15180     *  - A hex number of the ActivityRecord object instance.
15181     */
15182    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15183            int opti, boolean dumpAll) {
15184        ArrayList<ActivityRecord> activities;
15185
15186        synchronized (this) {
15187            activities = mStackSupervisor.getDumpActivitiesLocked(name);
15188        }
15189
15190        if (activities.size() <= 0) {
15191            return false;
15192        }
15193
15194        String[] newArgs = new String[args.length - opti];
15195        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15196
15197        TaskRecord lastTask = null;
15198        boolean needSep = false;
15199        for (int i=activities.size()-1; i>=0; i--) {
15200            ActivityRecord r = activities.get(i);
15201            if (needSep) {
15202                pw.println();
15203            }
15204            needSep = true;
15205            synchronized (this) {
15206                if (lastTask != r.task) {
15207                    lastTask = r.task;
15208                    pw.print("TASK "); pw.print(lastTask.affinity);
15209                            pw.print(" id="); pw.println(lastTask.taskId);
15210                    if (dumpAll) {
15211                        lastTask.dump(pw, "  ");
15212                    }
15213                }
15214            }
15215            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
15216        }
15217        return true;
15218    }
15219
15220    /**
15221     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
15222     * there is a thread associated with the activity.
15223     */
15224    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
15225            final ActivityRecord r, String[] args, boolean dumpAll) {
15226        String innerPrefix = prefix + "  ";
15227        synchronized (this) {
15228            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
15229                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
15230                    pw.print(" pid=");
15231                    if (r.app != null) pw.println(r.app.pid);
15232                    else pw.println("(not running)");
15233            if (dumpAll) {
15234                r.dump(pw, innerPrefix);
15235            }
15236        }
15237        if (r.app != null && r.app.thread != null) {
15238            // flush anything that is already in the PrintWriter since the thread is going
15239            // to write to the file descriptor directly
15240            pw.flush();
15241            try {
15242                TransferPipe tp = new TransferPipe();
15243                try {
15244                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
15245                            r.appToken, innerPrefix, args);
15246                    tp.go(fd);
15247                } finally {
15248                    tp.kill();
15249                }
15250            } catch (IOException e) {
15251                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
15252            } catch (RemoteException e) {
15253                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
15254            }
15255        }
15256    }
15257
15258    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15259            int opti, boolean dumpAll, String dumpPackage) {
15260        boolean needSep = false;
15261        boolean onlyHistory = false;
15262        boolean printedAnything = false;
15263
15264        if ("history".equals(dumpPackage)) {
15265            if (opti < args.length && "-s".equals(args[opti])) {
15266                dumpAll = false;
15267            }
15268            onlyHistory = true;
15269            dumpPackage = null;
15270        }
15271
15272        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
15273        if (!onlyHistory && dumpAll) {
15274            if (mRegisteredReceivers.size() > 0) {
15275                boolean printed = false;
15276                Iterator it = mRegisteredReceivers.values().iterator();
15277                while (it.hasNext()) {
15278                    ReceiverList r = (ReceiverList)it.next();
15279                    if (dumpPackage != null && (r.app == null ||
15280                            !dumpPackage.equals(r.app.info.packageName))) {
15281                        continue;
15282                    }
15283                    if (!printed) {
15284                        pw.println("  Registered Receivers:");
15285                        needSep = true;
15286                        printed = true;
15287                        printedAnything = true;
15288                    }
15289                    pw.print("  * "); pw.println(r);
15290                    r.dump(pw, "    ");
15291                }
15292            }
15293
15294            if (mReceiverResolver.dump(pw, needSep ?
15295                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
15296                    "    ", dumpPackage, false, false)) {
15297                needSep = true;
15298                printedAnything = true;
15299            }
15300        }
15301
15302        for (BroadcastQueue q : mBroadcastQueues) {
15303            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
15304            printedAnything |= needSep;
15305        }
15306
15307        needSep = true;
15308
15309        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
15310            for (int user=0; user<mStickyBroadcasts.size(); user++) {
15311                if (needSep) {
15312                    pw.println();
15313                }
15314                needSep = true;
15315                printedAnything = true;
15316                pw.print("  Sticky broadcasts for user ");
15317                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
15318                StringBuilder sb = new StringBuilder(128);
15319                for (Map.Entry<String, ArrayList<Intent>> ent
15320                        : mStickyBroadcasts.valueAt(user).entrySet()) {
15321                    pw.print("  * Sticky action "); pw.print(ent.getKey());
15322                    if (dumpAll) {
15323                        pw.println(":");
15324                        ArrayList<Intent> intents = ent.getValue();
15325                        final int N = intents.size();
15326                        for (int i=0; i<N; i++) {
15327                            sb.setLength(0);
15328                            sb.append("    Intent: ");
15329                            intents.get(i).toShortString(sb, false, true, false, false);
15330                            pw.println(sb.toString());
15331                            Bundle bundle = intents.get(i).getExtras();
15332                            if (bundle != null) {
15333                                pw.print("      ");
15334                                pw.println(bundle.toString());
15335                            }
15336                        }
15337                    } else {
15338                        pw.println("");
15339                    }
15340                }
15341            }
15342        }
15343
15344        if (!onlyHistory && dumpAll) {
15345            pw.println();
15346            for (BroadcastQueue queue : mBroadcastQueues) {
15347                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
15348                        + queue.mBroadcastsScheduled);
15349            }
15350            pw.println("  mHandler:");
15351            mHandler.dump(new PrintWriterPrinter(pw), "    ");
15352            needSep = true;
15353            printedAnything = true;
15354        }
15355
15356        if (!printedAnything) {
15357            pw.println("  (nothing)");
15358        }
15359    }
15360
15361    void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15362            int opti, boolean dumpAll, String dumpPackage) {
15363        if (mCurBroadcastStats == null) {
15364            return;
15365        }
15366
15367        pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
15368        final long now = SystemClock.elapsedRealtime();
15369        if (mLastBroadcastStats != null) {
15370            pw.print("  Last stats (from ");
15371            TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
15372            pw.print(" to ");
15373            TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
15374            pw.print(", ");
15375            TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
15376                    - mLastBroadcastStats.mStartUptime, pw);
15377            pw.println(" uptime):");
15378            if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15379                pw.println("    (nothing)");
15380            }
15381            pw.println();
15382        }
15383        pw.print("  Current stats (from ");
15384        TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
15385        pw.print(" to now, ");
15386        TimeUtils.formatDuration(SystemClock.uptimeMillis()
15387                - mCurBroadcastStats.mStartUptime, pw);
15388        pw.println(" uptime):");
15389        if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15390            pw.println("    (nothing)");
15391        }
15392    }
15393
15394    void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15395            int opti, boolean fullCheckin, String dumpPackage) {
15396        if (mCurBroadcastStats == null) {
15397            return;
15398        }
15399
15400        if (mLastBroadcastStats != null) {
15401            mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15402            if (fullCheckin) {
15403                mLastBroadcastStats = null;
15404                return;
15405            }
15406        }
15407        mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15408        if (fullCheckin) {
15409            mCurBroadcastStats = null;
15410        }
15411    }
15412
15413    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15414            int opti, boolean dumpAll, String dumpPackage) {
15415        boolean needSep;
15416        boolean printedAnything = false;
15417
15418        ItemMatcher matcher = new ItemMatcher();
15419        matcher.build(args, opti);
15420
15421        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
15422
15423        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
15424        printedAnything |= needSep;
15425
15426        if (mLaunchingProviders.size() > 0) {
15427            boolean printed = false;
15428            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
15429                ContentProviderRecord r = mLaunchingProviders.get(i);
15430                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
15431                    continue;
15432                }
15433                if (!printed) {
15434                    if (needSep) pw.println();
15435                    needSep = true;
15436                    pw.println("  Launching content providers:");
15437                    printed = true;
15438                    printedAnything = true;
15439                }
15440                pw.print("  Launching #"); pw.print(i); pw.print(": ");
15441                        pw.println(r);
15442            }
15443        }
15444
15445        if (!printedAnything) {
15446            pw.println("  (nothing)");
15447        }
15448    }
15449
15450    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15451            int opti, boolean dumpAll, String dumpPackage) {
15452        boolean needSep = false;
15453        boolean printedAnything = false;
15454
15455        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
15456
15457        if (mGrantedUriPermissions.size() > 0) {
15458            boolean printed = false;
15459            int dumpUid = -2;
15460            if (dumpPackage != null) {
15461                try {
15462                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
15463                            MATCH_UNINSTALLED_PACKAGES, 0);
15464                } catch (NameNotFoundException e) {
15465                    dumpUid = -1;
15466                }
15467            }
15468            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
15469                int uid = mGrantedUriPermissions.keyAt(i);
15470                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
15471                    continue;
15472                }
15473                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
15474                if (!printed) {
15475                    if (needSep) pw.println();
15476                    needSep = true;
15477                    pw.println("  Granted Uri Permissions:");
15478                    printed = true;
15479                    printedAnything = true;
15480                }
15481                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
15482                for (UriPermission perm : perms.values()) {
15483                    pw.print("    "); pw.println(perm);
15484                    if (dumpAll) {
15485                        perm.dump(pw, "      ");
15486                    }
15487                }
15488            }
15489        }
15490
15491        if (!printedAnything) {
15492            pw.println("  (nothing)");
15493        }
15494    }
15495
15496    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15497            int opti, boolean dumpAll, String dumpPackage) {
15498        boolean printed = false;
15499
15500        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
15501
15502        if (mIntentSenderRecords.size() > 0) {
15503            Iterator<WeakReference<PendingIntentRecord>> it
15504                    = mIntentSenderRecords.values().iterator();
15505            while (it.hasNext()) {
15506                WeakReference<PendingIntentRecord> ref = it.next();
15507                PendingIntentRecord rec = ref != null ? ref.get(): null;
15508                if (dumpPackage != null && (rec == null
15509                        || !dumpPackage.equals(rec.key.packageName))) {
15510                    continue;
15511                }
15512                printed = true;
15513                if (rec != null) {
15514                    pw.print("  * "); pw.println(rec);
15515                    if (dumpAll) {
15516                        rec.dump(pw, "    ");
15517                    }
15518                } else {
15519                    pw.print("  * "); pw.println(ref);
15520                }
15521            }
15522        }
15523
15524        if (!printed) {
15525            pw.println("  (nothing)");
15526        }
15527    }
15528
15529    private static final int dumpProcessList(PrintWriter pw,
15530            ActivityManagerService service, List list,
15531            String prefix, String normalLabel, String persistentLabel,
15532            String dumpPackage) {
15533        int numPers = 0;
15534        final int N = list.size()-1;
15535        for (int i=N; i>=0; i--) {
15536            ProcessRecord r = (ProcessRecord)list.get(i);
15537            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15538                continue;
15539            }
15540            pw.println(String.format("%s%s #%2d: %s",
15541                    prefix, (r.persistent ? persistentLabel : normalLabel),
15542                    i, r.toString()));
15543            if (r.persistent) {
15544                numPers++;
15545            }
15546        }
15547        return numPers;
15548    }
15549
15550    private static final boolean dumpProcessOomList(PrintWriter pw,
15551            ActivityManagerService service, List<ProcessRecord> origList,
15552            String prefix, String normalLabel, String persistentLabel,
15553            boolean inclDetails, String dumpPackage) {
15554
15555        ArrayList<Pair<ProcessRecord, Integer>> list
15556                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15557        for (int i=0; i<origList.size(); i++) {
15558            ProcessRecord r = origList.get(i);
15559            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15560                continue;
15561            }
15562            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15563        }
15564
15565        if (list.size() <= 0) {
15566            return false;
15567        }
15568
15569        Comparator<Pair<ProcessRecord, Integer>> comparator
15570                = new Comparator<Pair<ProcessRecord, Integer>>() {
15571            @Override
15572            public int compare(Pair<ProcessRecord, Integer> object1,
15573                    Pair<ProcessRecord, Integer> object2) {
15574                if (object1.first.setAdj != object2.first.setAdj) {
15575                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15576                }
15577                if (object1.first.setProcState != object2.first.setProcState) {
15578                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15579                }
15580                if (object1.second.intValue() != object2.second.intValue()) {
15581                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15582                }
15583                return 0;
15584            }
15585        };
15586
15587        Collections.sort(list, comparator);
15588
15589        final long curRealtime = SystemClock.elapsedRealtime();
15590        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15591        final long curUptime = SystemClock.uptimeMillis();
15592        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15593
15594        for (int i=list.size()-1; i>=0; i--) {
15595            ProcessRecord r = list.get(i).first;
15596            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15597            char schedGroup;
15598            switch (r.setSchedGroup) {
15599                case ProcessList.SCHED_GROUP_BACKGROUND:
15600                    schedGroup = 'B';
15601                    break;
15602                case ProcessList.SCHED_GROUP_DEFAULT:
15603                    schedGroup = 'F';
15604                    break;
15605                case ProcessList.SCHED_GROUP_TOP_APP:
15606                    schedGroup = 'T';
15607                    break;
15608                default:
15609                    schedGroup = '?';
15610                    break;
15611            }
15612            char foreground;
15613            if (r.foregroundActivities) {
15614                foreground = 'A';
15615            } else if (r.foregroundServices) {
15616                foreground = 'S';
15617            } else {
15618                foreground = ' ';
15619            }
15620            String procState = ProcessList.makeProcStateString(r.curProcState);
15621            pw.print(prefix);
15622            pw.print(r.persistent ? persistentLabel : normalLabel);
15623            pw.print(" #");
15624            int num = (origList.size()-1)-list.get(i).second;
15625            if (num < 10) pw.print(' ');
15626            pw.print(num);
15627            pw.print(": ");
15628            pw.print(oomAdj);
15629            pw.print(' ');
15630            pw.print(schedGroup);
15631            pw.print('/');
15632            pw.print(foreground);
15633            pw.print('/');
15634            pw.print(procState);
15635            pw.print(" trm:");
15636            if (r.trimMemoryLevel < 10) pw.print(' ');
15637            pw.print(r.trimMemoryLevel);
15638            pw.print(' ');
15639            pw.print(r.toShortString());
15640            pw.print(" (");
15641            pw.print(r.adjType);
15642            pw.println(')');
15643            if (r.adjSource != null || r.adjTarget != null) {
15644                pw.print(prefix);
15645                pw.print("    ");
15646                if (r.adjTarget instanceof ComponentName) {
15647                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15648                } else if (r.adjTarget != null) {
15649                    pw.print(r.adjTarget.toString());
15650                } else {
15651                    pw.print("{null}");
15652                }
15653                pw.print("<=");
15654                if (r.adjSource instanceof ProcessRecord) {
15655                    pw.print("Proc{");
15656                    pw.print(((ProcessRecord)r.adjSource).toShortString());
15657                    pw.println("}");
15658                } else if (r.adjSource != null) {
15659                    pw.println(r.adjSource.toString());
15660                } else {
15661                    pw.println("{null}");
15662                }
15663            }
15664            if (inclDetails) {
15665                pw.print(prefix);
15666                pw.print("    ");
15667                pw.print("oom: max="); pw.print(r.maxAdj);
15668                pw.print(" curRaw="); pw.print(r.curRawAdj);
15669                pw.print(" setRaw="); pw.print(r.setRawAdj);
15670                pw.print(" cur="); pw.print(r.curAdj);
15671                pw.print(" set="); pw.println(r.setAdj);
15672                pw.print(prefix);
15673                pw.print("    ");
15674                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15675                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15676                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15677                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15678                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15679                pw.println();
15680                pw.print(prefix);
15681                pw.print("    ");
15682                pw.print("cached="); pw.print(r.cached);
15683                pw.print(" empty="); pw.print(r.empty);
15684                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15685
15686                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15687                    if (r.lastWakeTime != 0) {
15688                        long wtime;
15689                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15690                        synchronized (stats) {
15691                            wtime = stats.getProcessWakeTime(r.info.uid,
15692                                    r.pid, curRealtime);
15693                        }
15694                        long timeUsed = wtime - r.lastWakeTime;
15695                        pw.print(prefix);
15696                        pw.print("    ");
15697                        pw.print("keep awake over ");
15698                        TimeUtils.formatDuration(realtimeSince, pw);
15699                        pw.print(" used ");
15700                        TimeUtils.formatDuration(timeUsed, pw);
15701                        pw.print(" (");
15702                        pw.print((timeUsed*100)/realtimeSince);
15703                        pw.println("%)");
15704                    }
15705                    if (r.lastCpuTime != 0) {
15706                        long timeUsed = r.curCpuTime - r.lastCpuTime;
15707                        pw.print(prefix);
15708                        pw.print("    ");
15709                        pw.print("run cpu over ");
15710                        TimeUtils.formatDuration(uptimeSince, pw);
15711                        pw.print(" used ");
15712                        TimeUtils.formatDuration(timeUsed, pw);
15713                        pw.print(" (");
15714                        pw.print((timeUsed*100)/uptimeSince);
15715                        pw.println("%)");
15716                    }
15717                }
15718            }
15719        }
15720        return true;
15721    }
15722
15723    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15724            String[] args) {
15725        ArrayList<ProcessRecord> procs;
15726        synchronized (this) {
15727            if (args != null && args.length > start
15728                    && args[start].charAt(0) != '-') {
15729                procs = new ArrayList<ProcessRecord>();
15730                int pid = -1;
15731                try {
15732                    pid = Integer.parseInt(args[start]);
15733                } catch (NumberFormatException e) {
15734                }
15735                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15736                    ProcessRecord proc = mLruProcesses.get(i);
15737                    if (proc.pid == pid) {
15738                        procs.add(proc);
15739                    } else if (allPkgs && proc.pkgList != null
15740                            && proc.pkgList.containsKey(args[start])) {
15741                        procs.add(proc);
15742                    } else if (proc.processName.equals(args[start])) {
15743                        procs.add(proc);
15744                    }
15745                }
15746                if (procs.size() <= 0) {
15747                    return null;
15748                }
15749            } else {
15750                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15751            }
15752        }
15753        return procs;
15754    }
15755
15756    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15757            PrintWriter pw, String[] args) {
15758        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15759        if (procs == null) {
15760            pw.println("No process found for: " + args[0]);
15761            return;
15762        }
15763
15764        long uptime = SystemClock.uptimeMillis();
15765        long realtime = SystemClock.elapsedRealtime();
15766        pw.println("Applications Graphics Acceleration Info:");
15767        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15768
15769        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15770            ProcessRecord r = procs.get(i);
15771            if (r.thread != null) {
15772                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15773                pw.flush();
15774                try {
15775                    TransferPipe tp = new TransferPipe();
15776                    try {
15777                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15778                        tp.go(fd);
15779                    } finally {
15780                        tp.kill();
15781                    }
15782                } catch (IOException e) {
15783                    pw.println("Failure while dumping the app: " + r);
15784                    pw.flush();
15785                } catch (RemoteException e) {
15786                    pw.println("Got a RemoteException while dumping the app " + r);
15787                    pw.flush();
15788                }
15789            }
15790        }
15791    }
15792
15793    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15794        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15795        if (procs == null) {
15796            pw.println("No process found for: " + args[0]);
15797            return;
15798        }
15799
15800        pw.println("Applications Database Info:");
15801
15802        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15803            ProcessRecord r = procs.get(i);
15804            if (r.thread != null) {
15805                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15806                pw.flush();
15807                try {
15808                    TransferPipe tp = new TransferPipe();
15809                    try {
15810                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15811                        tp.go(fd);
15812                    } finally {
15813                        tp.kill();
15814                    }
15815                } catch (IOException e) {
15816                    pw.println("Failure while dumping the app: " + r);
15817                    pw.flush();
15818                } catch (RemoteException e) {
15819                    pw.println("Got a RemoteException while dumping the app " + r);
15820                    pw.flush();
15821                }
15822            }
15823        }
15824    }
15825
15826    final static class MemItem {
15827        final boolean isProc;
15828        final String label;
15829        final String shortLabel;
15830        final long pss;
15831        final long swapPss;
15832        final int id;
15833        final boolean hasActivities;
15834        ArrayList<MemItem> subitems;
15835
15836        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15837                boolean _hasActivities) {
15838            isProc = true;
15839            label = _label;
15840            shortLabel = _shortLabel;
15841            pss = _pss;
15842            swapPss = _swapPss;
15843            id = _id;
15844            hasActivities = _hasActivities;
15845        }
15846
15847        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15848            isProc = false;
15849            label = _label;
15850            shortLabel = _shortLabel;
15851            pss = _pss;
15852            swapPss = _swapPss;
15853            id = _id;
15854            hasActivities = false;
15855        }
15856    }
15857
15858    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15859            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15860        if (sort && !isCompact) {
15861            Collections.sort(items, new Comparator<MemItem>() {
15862                @Override
15863                public int compare(MemItem lhs, MemItem rhs) {
15864                    if (lhs.pss < rhs.pss) {
15865                        return 1;
15866                    } else if (lhs.pss > rhs.pss) {
15867                        return -1;
15868                    }
15869                    return 0;
15870                }
15871            });
15872        }
15873
15874        for (int i=0; i<items.size(); i++) {
15875            MemItem mi = items.get(i);
15876            if (!isCompact) {
15877                if (dumpSwapPss) {
15878                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15879                            mi.label, stringifyKBSize(mi.swapPss));
15880                } else {
15881                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15882                }
15883            } else if (mi.isProc) {
15884                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15885                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15886                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15887                pw.println(mi.hasActivities ? ",a" : ",e");
15888            } else {
15889                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15890                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15891            }
15892            if (mi.subitems != null) {
15893                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15894                        true, isCompact, dumpSwapPss);
15895            }
15896        }
15897    }
15898
15899    // These are in KB.
15900    static final long[] DUMP_MEM_BUCKETS = new long[] {
15901        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15902        120*1024, 160*1024, 200*1024,
15903        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15904        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15905    };
15906
15907    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15908            boolean stackLike) {
15909        int start = label.lastIndexOf('.');
15910        if (start >= 0) start++;
15911        else start = 0;
15912        int end = label.length();
15913        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15914            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15915                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15916                out.append(bucket);
15917                out.append(stackLike ? "MB." : "MB ");
15918                out.append(label, start, end);
15919                return;
15920            }
15921        }
15922        out.append(memKB/1024);
15923        out.append(stackLike ? "MB." : "MB ");
15924        out.append(label, start, end);
15925    }
15926
15927    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15928            ProcessList.NATIVE_ADJ,
15929            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15930            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15931            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15932            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15933            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15934            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
15935    };
15936    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15937            "Native",
15938            "System", "Persistent", "Persistent Service", "Foreground",
15939            "Visible", "Perceptible",
15940            "Heavy Weight", "Backup",
15941            "A Services", "Home",
15942            "Previous", "B Services", "Cached"
15943    };
15944    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15945            "native",
15946            "sys", "pers", "persvc", "fore",
15947            "vis", "percept",
15948            "heavy", "backup",
15949            "servicea", "home",
15950            "prev", "serviceb", "cached"
15951    };
15952
15953    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15954            long realtime, boolean isCheckinRequest, boolean isCompact) {
15955        if (isCompact) {
15956            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15957        }
15958        if (isCheckinRequest || isCompact) {
15959            // short checkin version
15960            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15961        } else {
15962            pw.println("Applications Memory Usage (in Kilobytes):");
15963            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15964        }
15965    }
15966
15967    private static final int KSM_SHARED = 0;
15968    private static final int KSM_SHARING = 1;
15969    private static final int KSM_UNSHARED = 2;
15970    private static final int KSM_VOLATILE = 3;
15971
15972    private final long[] getKsmInfo() {
15973        long[] longOut = new long[4];
15974        final int[] SINGLE_LONG_FORMAT = new int[] {
15975            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15976        };
15977        long[] longTmp = new long[1];
15978        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15979                SINGLE_LONG_FORMAT, null, longTmp, null);
15980        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15981        longTmp[0] = 0;
15982        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15983                SINGLE_LONG_FORMAT, null, longTmp, null);
15984        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15985        longTmp[0] = 0;
15986        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15987                SINGLE_LONG_FORMAT, null, longTmp, null);
15988        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15989        longTmp[0] = 0;
15990        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15991                SINGLE_LONG_FORMAT, null, longTmp, null);
15992        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15993        return longOut;
15994    }
15995
15996    private static String stringifySize(long size, int order) {
15997        Locale locale = Locale.US;
15998        switch (order) {
15999            case 1:
16000                return String.format(locale, "%,13d", size);
16001            case 1024:
16002                return String.format(locale, "%,9dK", size / 1024);
16003            case 1024 * 1024:
16004                return String.format(locale, "%,5dM", size / 1024 / 1024);
16005            case 1024 * 1024 * 1024:
16006                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
16007            default:
16008                throw new IllegalArgumentException("Invalid size order");
16009        }
16010    }
16011
16012    private static String stringifyKBSize(long size) {
16013        return stringifySize(size * 1024, 1024);
16014    }
16015
16016    // Update this version number in case you change the 'compact' format
16017    private static final int MEMINFO_COMPACT_VERSION = 1;
16018
16019    final void dumpApplicationMemoryUsage(FileDescriptor fd,
16020            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
16021        boolean dumpDetails = false;
16022        boolean dumpFullDetails = false;
16023        boolean dumpDalvik = false;
16024        boolean dumpSummaryOnly = false;
16025        boolean dumpUnreachable = false;
16026        boolean oomOnly = false;
16027        boolean isCompact = false;
16028        boolean localOnly = false;
16029        boolean packages = false;
16030        boolean isCheckinRequest = false;
16031        boolean dumpSwapPss = false;
16032
16033        int opti = 0;
16034        while (opti < args.length) {
16035            String opt = args[opti];
16036            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
16037                break;
16038            }
16039            opti++;
16040            if ("-a".equals(opt)) {
16041                dumpDetails = true;
16042                dumpFullDetails = true;
16043                dumpDalvik = true;
16044                dumpSwapPss = true;
16045            } else if ("-d".equals(opt)) {
16046                dumpDalvik = true;
16047            } else if ("-c".equals(opt)) {
16048                isCompact = true;
16049            } else if ("-s".equals(opt)) {
16050                dumpDetails = true;
16051                dumpSummaryOnly = true;
16052            } else if ("-S".equals(opt)) {
16053                dumpSwapPss = true;
16054            } else if ("--unreachable".equals(opt)) {
16055                dumpUnreachable = true;
16056            } else if ("--oom".equals(opt)) {
16057                oomOnly = true;
16058            } else if ("--local".equals(opt)) {
16059                localOnly = true;
16060            } else if ("--package".equals(opt)) {
16061                packages = true;
16062            } else if ("--checkin".equals(opt)) {
16063                isCheckinRequest = true;
16064
16065            } else if ("-h".equals(opt)) {
16066                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
16067                pw.println("  -a: include all available information for each process.");
16068                pw.println("  -d: include dalvik details.");
16069                pw.println("  -c: dump in a compact machine-parseable representation.");
16070                pw.println("  -s: dump only summary of application memory usage.");
16071                pw.println("  -S: dump also SwapPss.");
16072                pw.println("  --oom: only show processes organized by oom adj.");
16073                pw.println("  --local: only collect details locally, don't call process.");
16074                pw.println("  --package: interpret process arg as package, dumping all");
16075                pw.println("             processes that have loaded that package.");
16076                pw.println("  --checkin: dump data for a checkin");
16077                pw.println("If [process] is specified it can be the name or ");
16078                pw.println("pid of a specific process to dump.");
16079                return;
16080            } else {
16081                pw.println("Unknown argument: " + opt + "; use -h for help");
16082            }
16083        }
16084
16085        long uptime = SystemClock.uptimeMillis();
16086        long realtime = SystemClock.elapsedRealtime();
16087        final long[] tmpLong = new long[1];
16088
16089        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
16090        if (procs == null) {
16091            // No Java processes.  Maybe they want to print a native process.
16092            if (args != null && args.length > opti
16093                    && args[opti].charAt(0) != '-') {
16094                ArrayList<ProcessCpuTracker.Stats> nativeProcs
16095                        = new ArrayList<ProcessCpuTracker.Stats>();
16096                updateCpuStatsNow();
16097                int findPid = -1;
16098                try {
16099                    findPid = Integer.parseInt(args[opti]);
16100                } catch (NumberFormatException e) {
16101                }
16102                synchronized (mProcessCpuTracker) {
16103                    final int N = mProcessCpuTracker.countStats();
16104                    for (int i=0; i<N; i++) {
16105                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16106                        if (st.pid == findPid || (st.baseName != null
16107                                && st.baseName.equals(args[opti]))) {
16108                            nativeProcs.add(st);
16109                        }
16110                    }
16111                }
16112                if (nativeProcs.size() > 0) {
16113                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
16114                            isCompact);
16115                    Debug.MemoryInfo mi = null;
16116                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
16117                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
16118                        final int pid = r.pid;
16119                        if (!isCheckinRequest && dumpDetails) {
16120                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
16121                        }
16122                        if (mi == null) {
16123                            mi = new Debug.MemoryInfo();
16124                        }
16125                        if (dumpDetails || (!brief && !oomOnly)) {
16126                            Debug.getMemoryInfo(pid, mi);
16127                        } else {
16128                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16129                            mi.dalvikPrivateDirty = (int)tmpLong[0];
16130                        }
16131                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16132                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
16133                        if (isCheckinRequest) {
16134                            pw.println();
16135                        }
16136                    }
16137                    return;
16138                }
16139            }
16140            pw.println("No process found for: " + args[opti]);
16141            return;
16142        }
16143
16144        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
16145            dumpDetails = true;
16146        }
16147
16148        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
16149
16150        String[] innerArgs = new String[args.length-opti];
16151        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
16152
16153        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
16154        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
16155        long nativePss = 0;
16156        long nativeSwapPss = 0;
16157        long dalvikPss = 0;
16158        long dalvikSwapPss = 0;
16159        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16160                EmptyArray.LONG;
16161        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16162                EmptyArray.LONG;
16163        long otherPss = 0;
16164        long otherSwapPss = 0;
16165        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16166        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16167
16168        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16169        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16170        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
16171                new ArrayList[DUMP_MEM_OOM_LABEL.length];
16172
16173        long totalPss = 0;
16174        long totalSwapPss = 0;
16175        long cachedPss = 0;
16176        long cachedSwapPss = 0;
16177        boolean hasSwapPss = false;
16178
16179        Debug.MemoryInfo mi = null;
16180        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16181            final ProcessRecord r = procs.get(i);
16182            final IApplicationThread thread;
16183            final int pid;
16184            final int oomAdj;
16185            final boolean hasActivities;
16186            synchronized (this) {
16187                thread = r.thread;
16188                pid = r.pid;
16189                oomAdj = r.getSetAdjWithServices();
16190                hasActivities = r.activities.size() > 0;
16191            }
16192            if (thread != null) {
16193                if (!isCheckinRequest && dumpDetails) {
16194                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
16195                }
16196                if (mi == null) {
16197                    mi = new Debug.MemoryInfo();
16198                }
16199                if (dumpDetails || (!brief && !oomOnly)) {
16200                    Debug.getMemoryInfo(pid, mi);
16201                    hasSwapPss = mi.hasSwappedOutPss;
16202                } else {
16203                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16204                    mi.dalvikPrivateDirty = (int)tmpLong[0];
16205                }
16206                if (dumpDetails) {
16207                    if (localOnly) {
16208                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16209                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
16210                        if (isCheckinRequest) {
16211                            pw.println();
16212                        }
16213                    } else {
16214                        try {
16215                            pw.flush();
16216                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
16217                                    dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
16218                        } catch (RemoteException e) {
16219                            if (!isCheckinRequest) {
16220                                pw.println("Got RemoteException!");
16221                                pw.flush();
16222                            }
16223                        }
16224                    }
16225                }
16226
16227                final long myTotalPss = mi.getTotalPss();
16228                final long myTotalUss = mi.getTotalUss();
16229                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16230
16231                synchronized (this) {
16232                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
16233                        // Record this for posterity if the process has been stable.
16234                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
16235                    }
16236                }
16237
16238                if (!isCheckinRequest && mi != null) {
16239                    totalPss += myTotalPss;
16240                    totalSwapPss += myTotalSwapPss;
16241                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
16242                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
16243                            myTotalSwapPss, pid, hasActivities);
16244                    procMems.add(pssItem);
16245                    procMemsMap.put(pid, pssItem);
16246
16247                    nativePss += mi.nativePss;
16248                    nativeSwapPss += mi.nativeSwappedOutPss;
16249                    dalvikPss += mi.dalvikPss;
16250                    dalvikSwapPss += mi.dalvikSwappedOutPss;
16251                    for (int j=0; j<dalvikSubitemPss.length; j++) {
16252                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16253                        dalvikSubitemSwapPss[j] +=
16254                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16255                    }
16256                    otherPss += mi.otherPss;
16257                    otherSwapPss += mi.otherSwappedOutPss;
16258                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16259                        long mem = mi.getOtherPss(j);
16260                        miscPss[j] += mem;
16261                        otherPss -= mem;
16262                        mem = mi.getOtherSwappedOutPss(j);
16263                        miscSwapPss[j] += mem;
16264                        otherSwapPss -= mem;
16265                    }
16266
16267                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16268                        cachedPss += myTotalPss;
16269                        cachedSwapPss += myTotalSwapPss;
16270                    }
16271
16272                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
16273                        if (oomIndex == (oomPss.length - 1)
16274                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
16275                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
16276                            oomPss[oomIndex] += myTotalPss;
16277                            oomSwapPss[oomIndex] += myTotalSwapPss;
16278                            if (oomProcs[oomIndex] == null) {
16279                                oomProcs[oomIndex] = new ArrayList<MemItem>();
16280                            }
16281                            oomProcs[oomIndex].add(pssItem);
16282                            break;
16283                        }
16284                    }
16285                }
16286            }
16287        }
16288
16289        long nativeProcTotalPss = 0;
16290
16291        if (!isCheckinRequest && procs.size() > 1 && !packages) {
16292            // If we are showing aggregations, also look for native processes to
16293            // include so that our aggregations are more accurate.
16294            updateCpuStatsNow();
16295            mi = null;
16296            synchronized (mProcessCpuTracker) {
16297                final int N = mProcessCpuTracker.countStats();
16298                for (int i=0; i<N; i++) {
16299                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16300                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
16301                        if (mi == null) {
16302                            mi = new Debug.MemoryInfo();
16303                        }
16304                        if (!brief && !oomOnly) {
16305                            Debug.getMemoryInfo(st.pid, mi);
16306                        } else {
16307                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
16308                            mi.nativePrivateDirty = (int)tmpLong[0];
16309                        }
16310
16311                        final long myTotalPss = mi.getTotalPss();
16312                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16313                        totalPss += myTotalPss;
16314                        nativeProcTotalPss += myTotalPss;
16315
16316                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
16317                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
16318                        procMems.add(pssItem);
16319
16320                        nativePss += mi.nativePss;
16321                        nativeSwapPss += mi.nativeSwappedOutPss;
16322                        dalvikPss += mi.dalvikPss;
16323                        dalvikSwapPss += mi.dalvikSwappedOutPss;
16324                        for (int j=0; j<dalvikSubitemPss.length; j++) {
16325                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16326                            dalvikSubitemSwapPss[j] +=
16327                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16328                        }
16329                        otherPss += mi.otherPss;
16330                        otherSwapPss += mi.otherSwappedOutPss;
16331                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16332                            long mem = mi.getOtherPss(j);
16333                            miscPss[j] += mem;
16334                            otherPss -= mem;
16335                            mem = mi.getOtherSwappedOutPss(j);
16336                            miscSwapPss[j] += mem;
16337                            otherSwapPss -= mem;
16338                        }
16339                        oomPss[0] += myTotalPss;
16340                        oomSwapPss[0] += myTotalSwapPss;
16341                        if (oomProcs[0] == null) {
16342                            oomProcs[0] = new ArrayList<MemItem>();
16343                        }
16344                        oomProcs[0].add(pssItem);
16345                    }
16346                }
16347            }
16348
16349            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
16350
16351            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
16352            final MemItem dalvikItem =
16353                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
16354            if (dalvikSubitemPss.length > 0) {
16355                dalvikItem.subitems = new ArrayList<MemItem>();
16356                for (int j=0; j<dalvikSubitemPss.length; j++) {
16357                    final String name = Debug.MemoryInfo.getOtherLabel(
16358                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
16359                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
16360                                    dalvikSubitemSwapPss[j], j));
16361                }
16362            }
16363            catMems.add(dalvikItem);
16364            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
16365            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16366                String label = Debug.MemoryInfo.getOtherLabel(j);
16367                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
16368            }
16369
16370            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
16371            for (int j=0; j<oomPss.length; j++) {
16372                if (oomPss[j] != 0) {
16373                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
16374                            : DUMP_MEM_OOM_LABEL[j];
16375                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
16376                            DUMP_MEM_OOM_ADJ[j]);
16377                    item.subitems = oomProcs[j];
16378                    oomMems.add(item);
16379                }
16380            }
16381
16382            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
16383            if (!brief && !oomOnly && !isCompact) {
16384                pw.println();
16385                pw.println("Total PSS by process:");
16386                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
16387                pw.println();
16388            }
16389            if (!isCompact) {
16390                pw.println("Total PSS by OOM adjustment:");
16391            }
16392            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
16393            if (!brief && !oomOnly) {
16394                PrintWriter out = categoryPw != null ? categoryPw : pw;
16395                if (!isCompact) {
16396                    out.println();
16397                    out.println("Total PSS by category:");
16398                }
16399                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
16400            }
16401            if (!isCompact) {
16402                pw.println();
16403            }
16404            MemInfoReader memInfo = new MemInfoReader();
16405            memInfo.readMemInfo();
16406            if (nativeProcTotalPss > 0) {
16407                synchronized (this) {
16408                    final long cachedKb = memInfo.getCachedSizeKb();
16409                    final long freeKb = memInfo.getFreeSizeKb();
16410                    final long zramKb = memInfo.getZramTotalSizeKb();
16411                    final long kernelKb = memInfo.getKernelUsedSizeKb();
16412                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
16413                            kernelKb*1024, nativeProcTotalPss*1024);
16414                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
16415                            nativeProcTotalPss);
16416                }
16417            }
16418            if (!brief) {
16419                if (!isCompact) {
16420                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
16421                    pw.print(" (status ");
16422                    switch (mLastMemoryLevel) {
16423                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
16424                            pw.println("normal)");
16425                            break;
16426                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
16427                            pw.println("moderate)");
16428                            break;
16429                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
16430                            pw.println("low)");
16431                            break;
16432                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16433                            pw.println("critical)");
16434                            break;
16435                        default:
16436                            pw.print(mLastMemoryLevel);
16437                            pw.println(")");
16438                            break;
16439                    }
16440                    pw.print(" Free RAM: ");
16441                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16442                            + memInfo.getFreeSizeKb()));
16443                    pw.print(" (");
16444                    pw.print(stringifyKBSize(cachedPss));
16445                    pw.print(" cached pss + ");
16446                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
16447                    pw.print(" cached kernel + ");
16448                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
16449                    pw.println(" free)");
16450                } else {
16451                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
16452                    pw.print(cachedPss + memInfo.getCachedSizeKb()
16453                            + memInfo.getFreeSizeKb()); pw.print(",");
16454                    pw.println(totalPss - cachedPss);
16455                }
16456            }
16457            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
16458                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16459                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
16460            if (!isCompact) {
16461                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
16462                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
16463                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
16464                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
16465                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
16466            } else {
16467                pw.print("lostram,"); pw.println(lostRAM);
16468            }
16469            if (!brief) {
16470                if (memInfo.getZramTotalSizeKb() != 0) {
16471                    if (!isCompact) {
16472                        pw.print("     ZRAM: ");
16473                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
16474                                pw.print(" physical used for ");
16475                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
16476                                        - memInfo.getSwapFreeSizeKb()));
16477                                pw.print(" in swap (");
16478                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
16479                                pw.println(" total swap)");
16480                    } else {
16481                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
16482                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
16483                                pw.println(memInfo.getSwapFreeSizeKb());
16484                    }
16485                }
16486                final long[] ksm = getKsmInfo();
16487                if (!isCompact) {
16488                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16489                            || ksm[KSM_VOLATILE] != 0) {
16490                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
16491                                pw.print(" saved from shared ");
16492                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
16493                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
16494                                pw.print(" unshared; ");
16495                                pw.print(stringifyKBSize(
16496                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
16497                    }
16498                    pw.print("   Tuning: ");
16499                    pw.print(ActivityManager.staticGetMemoryClass());
16500                    pw.print(" (large ");
16501                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16502                    pw.print("), oom ");
16503                    pw.print(stringifySize(
16504                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
16505                    pw.print(", restore limit ");
16506                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
16507                    if (ActivityManager.isLowRamDeviceStatic()) {
16508                        pw.print(" (low-ram)");
16509                    }
16510                    if (ActivityManager.isHighEndGfx()) {
16511                        pw.print(" (high-end-gfx)");
16512                    }
16513                    pw.println();
16514                } else {
16515                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16516                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16517                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16518                    pw.print("tuning,");
16519                    pw.print(ActivityManager.staticGetMemoryClass());
16520                    pw.print(',');
16521                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16522                    pw.print(',');
16523                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16524                    if (ActivityManager.isLowRamDeviceStatic()) {
16525                        pw.print(",low-ram");
16526                    }
16527                    if (ActivityManager.isHighEndGfx()) {
16528                        pw.print(",high-end-gfx");
16529                    }
16530                    pw.println();
16531                }
16532            }
16533        }
16534    }
16535
16536    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16537            long memtrack, String name) {
16538        sb.append("  ");
16539        sb.append(ProcessList.makeOomAdjString(oomAdj));
16540        sb.append(' ');
16541        sb.append(ProcessList.makeProcStateString(procState));
16542        sb.append(' ');
16543        ProcessList.appendRamKb(sb, pss);
16544        sb.append(": ");
16545        sb.append(name);
16546        if (memtrack > 0) {
16547            sb.append(" (");
16548            sb.append(stringifyKBSize(memtrack));
16549            sb.append(" memtrack)");
16550        }
16551    }
16552
16553    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16554        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16555        sb.append(" (pid ");
16556        sb.append(mi.pid);
16557        sb.append(") ");
16558        sb.append(mi.adjType);
16559        sb.append('\n');
16560        if (mi.adjReason != null) {
16561            sb.append("                      ");
16562            sb.append(mi.adjReason);
16563            sb.append('\n');
16564        }
16565    }
16566
16567    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16568        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16569        for (int i=0, N=memInfos.size(); i<N; i++) {
16570            ProcessMemInfo mi = memInfos.get(i);
16571            infoMap.put(mi.pid, mi);
16572        }
16573        updateCpuStatsNow();
16574        long[] memtrackTmp = new long[1];
16575        final List<ProcessCpuTracker.Stats> stats;
16576        // Get a list of Stats that have vsize > 0
16577        synchronized (mProcessCpuTracker) {
16578            stats = mProcessCpuTracker.getStats((st) -> {
16579                return st.vsize > 0;
16580            });
16581        }
16582        final int statsCount = stats.size();
16583        for (int i = 0; i < statsCount; i++) {
16584            ProcessCpuTracker.Stats st = stats.get(i);
16585            long pss = Debug.getPss(st.pid, null, memtrackTmp);
16586            if (pss > 0) {
16587                if (infoMap.indexOfKey(st.pid) < 0) {
16588                    ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16589                            ProcessList.NATIVE_ADJ, -1, "native", null);
16590                    mi.pss = pss;
16591                    mi.memtrack = memtrackTmp[0];
16592                    memInfos.add(mi);
16593                }
16594            }
16595        }
16596
16597        long totalPss = 0;
16598        long totalMemtrack = 0;
16599        for (int i=0, N=memInfos.size(); i<N; i++) {
16600            ProcessMemInfo mi = memInfos.get(i);
16601            if (mi.pss == 0) {
16602                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16603                mi.memtrack = memtrackTmp[0];
16604            }
16605            totalPss += mi.pss;
16606            totalMemtrack += mi.memtrack;
16607        }
16608        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16609            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16610                if (lhs.oomAdj != rhs.oomAdj) {
16611                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16612                }
16613                if (lhs.pss != rhs.pss) {
16614                    return lhs.pss < rhs.pss ? 1 : -1;
16615                }
16616                return 0;
16617            }
16618        });
16619
16620        StringBuilder tag = new StringBuilder(128);
16621        StringBuilder stack = new StringBuilder(128);
16622        tag.append("Low on memory -- ");
16623        appendMemBucket(tag, totalPss, "total", false);
16624        appendMemBucket(stack, totalPss, "total", true);
16625
16626        StringBuilder fullNativeBuilder = new StringBuilder(1024);
16627        StringBuilder shortNativeBuilder = new StringBuilder(1024);
16628        StringBuilder fullJavaBuilder = new StringBuilder(1024);
16629
16630        boolean firstLine = true;
16631        int lastOomAdj = Integer.MIN_VALUE;
16632        long extraNativeRam = 0;
16633        long extraNativeMemtrack = 0;
16634        long cachedPss = 0;
16635        for (int i=0, N=memInfos.size(); i<N; i++) {
16636            ProcessMemInfo mi = memInfos.get(i);
16637
16638            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16639                cachedPss += mi.pss;
16640            }
16641
16642            if (mi.oomAdj != ProcessList.NATIVE_ADJ
16643                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
16644                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
16645                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16646                if (lastOomAdj != mi.oomAdj) {
16647                    lastOomAdj = mi.oomAdj;
16648                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16649                        tag.append(" / ");
16650                    }
16651                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16652                        if (firstLine) {
16653                            stack.append(":");
16654                            firstLine = false;
16655                        }
16656                        stack.append("\n\t at ");
16657                    } else {
16658                        stack.append("$");
16659                    }
16660                } else {
16661                    tag.append(" ");
16662                    stack.append("$");
16663                }
16664                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16665                    appendMemBucket(tag, mi.pss, mi.name, false);
16666                }
16667                appendMemBucket(stack, mi.pss, mi.name, true);
16668                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16669                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16670                    stack.append("(");
16671                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16672                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16673                            stack.append(DUMP_MEM_OOM_LABEL[k]);
16674                            stack.append(":");
16675                            stack.append(DUMP_MEM_OOM_ADJ[k]);
16676                        }
16677                    }
16678                    stack.append(")");
16679                }
16680            }
16681
16682            appendMemInfo(fullNativeBuilder, mi);
16683            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16684                // The short form only has native processes that are >= 512K.
16685                if (mi.pss >= 512) {
16686                    appendMemInfo(shortNativeBuilder, mi);
16687                } else {
16688                    extraNativeRam += mi.pss;
16689                    extraNativeMemtrack += mi.memtrack;
16690                }
16691            } else {
16692                // Short form has all other details, but if we have collected RAM
16693                // from smaller native processes let's dump a summary of that.
16694                if (extraNativeRam > 0) {
16695                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16696                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16697                    shortNativeBuilder.append('\n');
16698                    extraNativeRam = 0;
16699                }
16700                appendMemInfo(fullJavaBuilder, mi);
16701            }
16702        }
16703
16704        fullJavaBuilder.append("           ");
16705        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16706        fullJavaBuilder.append(": TOTAL");
16707        if (totalMemtrack > 0) {
16708            fullJavaBuilder.append(" (");
16709            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16710            fullJavaBuilder.append(" memtrack)");
16711        } else {
16712        }
16713        fullJavaBuilder.append("\n");
16714
16715        MemInfoReader memInfo = new MemInfoReader();
16716        memInfo.readMemInfo();
16717        final long[] infos = memInfo.getRawInfo();
16718
16719        StringBuilder memInfoBuilder = new StringBuilder(1024);
16720        Debug.getMemInfo(infos);
16721        memInfoBuilder.append("  MemInfo: ");
16722        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16723        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16724        memInfoBuilder.append(stringifyKBSize(
16725                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16726        memInfoBuilder.append(stringifyKBSize(
16727                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16728        memInfoBuilder.append(stringifyKBSize(
16729                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16730        memInfoBuilder.append("           ");
16731        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16732        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16733        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16734        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16735        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16736            memInfoBuilder.append("  ZRAM: ");
16737            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16738            memInfoBuilder.append(" RAM, ");
16739            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16740            memInfoBuilder.append(" swap total, ");
16741            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16742            memInfoBuilder.append(" swap free\n");
16743        }
16744        final long[] ksm = getKsmInfo();
16745        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16746                || ksm[KSM_VOLATILE] != 0) {
16747            memInfoBuilder.append("  KSM: ");
16748            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16749            memInfoBuilder.append(" saved from shared ");
16750            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16751            memInfoBuilder.append("\n       ");
16752            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16753            memInfoBuilder.append(" unshared; ");
16754            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16755            memInfoBuilder.append(" volatile\n");
16756        }
16757        memInfoBuilder.append("  Free RAM: ");
16758        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16759                + memInfo.getFreeSizeKb()));
16760        memInfoBuilder.append("\n");
16761        memInfoBuilder.append("  Used RAM: ");
16762        memInfoBuilder.append(stringifyKBSize(
16763                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16764        memInfoBuilder.append("\n");
16765        memInfoBuilder.append("  Lost RAM: ");
16766        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16767                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16768                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16769        memInfoBuilder.append("\n");
16770        Slog.i(TAG, "Low on memory:");
16771        Slog.i(TAG, shortNativeBuilder.toString());
16772        Slog.i(TAG, fullJavaBuilder.toString());
16773        Slog.i(TAG, memInfoBuilder.toString());
16774
16775        StringBuilder dropBuilder = new StringBuilder(1024);
16776        /*
16777        StringWriter oomSw = new StringWriter();
16778        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16779        StringWriter catSw = new StringWriter();
16780        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16781        String[] emptyArgs = new String[] { };
16782        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16783        oomPw.flush();
16784        String oomString = oomSw.toString();
16785        */
16786        dropBuilder.append("Low on memory:");
16787        dropBuilder.append(stack);
16788        dropBuilder.append('\n');
16789        dropBuilder.append(fullNativeBuilder);
16790        dropBuilder.append(fullJavaBuilder);
16791        dropBuilder.append('\n');
16792        dropBuilder.append(memInfoBuilder);
16793        dropBuilder.append('\n');
16794        /*
16795        dropBuilder.append(oomString);
16796        dropBuilder.append('\n');
16797        */
16798        StringWriter catSw = new StringWriter();
16799        synchronized (ActivityManagerService.this) {
16800            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16801            String[] emptyArgs = new String[] { };
16802            catPw.println();
16803            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16804            catPw.println();
16805            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
16806                    false, null).dumpLocked();
16807            catPw.println();
16808            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16809            catPw.flush();
16810        }
16811        dropBuilder.append(catSw.toString());
16812        addErrorToDropBox("lowmem", null, "system_server", null,
16813                null, tag.toString(), dropBuilder.toString(), null, null);
16814        //Slog.i(TAG, "Sent to dropbox:");
16815        //Slog.i(TAG, dropBuilder.toString());
16816        synchronized (ActivityManagerService.this) {
16817            long now = SystemClock.uptimeMillis();
16818            if (mLastMemUsageReportTime < now) {
16819                mLastMemUsageReportTime = now;
16820            }
16821        }
16822    }
16823
16824    /**
16825     * Searches array of arguments for the specified string
16826     * @param args array of argument strings
16827     * @param value value to search for
16828     * @return true if the value is contained in the array
16829     */
16830    private static boolean scanArgs(String[] args, String value) {
16831        if (args != null) {
16832            for (String arg : args) {
16833                if (value.equals(arg)) {
16834                    return true;
16835                }
16836            }
16837        }
16838        return false;
16839    }
16840
16841    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16842            ContentProviderRecord cpr, boolean always) {
16843        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16844
16845        if (!inLaunching || always) {
16846            synchronized (cpr) {
16847                cpr.launchingApp = null;
16848                cpr.notifyAll();
16849            }
16850            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16851            String names[] = cpr.info.authority.split(";");
16852            for (int j = 0; j < names.length; j++) {
16853                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16854            }
16855        }
16856
16857        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16858            ContentProviderConnection conn = cpr.connections.get(i);
16859            if (conn.waiting) {
16860                // If this connection is waiting for the provider, then we don't
16861                // need to mess with its process unless we are always removing
16862                // or for some reason the provider is not currently launching.
16863                if (inLaunching && !always) {
16864                    continue;
16865                }
16866            }
16867            ProcessRecord capp = conn.client;
16868            conn.dead = true;
16869            if (conn.stableCount > 0) {
16870                if (!capp.persistent && capp.thread != null
16871                        && capp.pid != 0
16872                        && capp.pid != MY_PID) {
16873                    capp.kill("depends on provider "
16874                            + cpr.name.flattenToShortString()
16875                            + " in dying proc " + (proc != null ? proc.processName : "??")
16876                            + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
16877                }
16878            } else if (capp.thread != null && conn.provider.provider != null) {
16879                try {
16880                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16881                } catch (RemoteException e) {
16882                }
16883                // In the protocol here, we don't expect the client to correctly
16884                // clean up this connection, we'll just remove it.
16885                cpr.connections.remove(i);
16886                if (conn.client.conProviders.remove(conn)) {
16887                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16888                }
16889            }
16890        }
16891
16892        if (inLaunching && always) {
16893            mLaunchingProviders.remove(cpr);
16894        }
16895        return inLaunching;
16896    }
16897
16898    /**
16899     * Main code for cleaning up a process when it has gone away.  This is
16900     * called both as a result of the process dying, or directly when stopping
16901     * a process when running in single process mode.
16902     *
16903     * @return Returns true if the given process has been restarted, so the
16904     * app that was passed in must remain on the process lists.
16905     */
16906    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16907            boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
16908        Slog.d(TAG, "cleanUpApplicationRecord -- " + app.pid);
16909        if (index >= 0) {
16910            removeLruProcessLocked(app);
16911            ProcessList.remove(app.pid);
16912        }
16913
16914        mProcessesToGc.remove(app);
16915        mPendingPssProcesses.remove(app);
16916
16917        // Dismiss any open dialogs.
16918        if (app.crashDialog != null && !app.forceCrashReport) {
16919            app.crashDialog.dismiss();
16920            app.crashDialog = null;
16921        }
16922        if (app.anrDialog != null) {
16923            app.anrDialog.dismiss();
16924            app.anrDialog = null;
16925        }
16926        if (app.waitDialog != null) {
16927            app.waitDialog.dismiss();
16928            app.waitDialog = null;
16929        }
16930
16931        app.crashing = false;
16932        app.notResponding = false;
16933
16934        app.resetPackageList(mProcessStats);
16935        app.unlinkDeathRecipient();
16936        app.makeInactive(mProcessStats);
16937        app.waitingToKill = null;
16938        app.forcingToForeground = null;
16939        updateProcessForegroundLocked(app, false, false);
16940        app.foregroundActivities = false;
16941        app.hasShownUi = false;
16942        app.treatLikeActivity = false;
16943        app.hasAboveClient = false;
16944        app.hasClientActivities = false;
16945
16946        mServices.killServicesLocked(app, allowRestart);
16947
16948        boolean restart = false;
16949
16950        // Remove published content providers.
16951        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16952            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16953            final boolean always = app.bad || !allowRestart;
16954            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16955            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16956                // We left the provider in the launching list, need to
16957                // restart it.
16958                restart = true;
16959            }
16960
16961            cpr.provider = null;
16962            cpr.proc = null;
16963        }
16964        app.pubProviders.clear();
16965
16966        // Take care of any launching providers waiting for this process.
16967        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16968            restart = true;
16969        }
16970
16971        // Unregister from connected content providers.
16972        if (!app.conProviders.isEmpty()) {
16973            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16974                ContentProviderConnection conn = app.conProviders.get(i);
16975                conn.provider.connections.remove(conn);
16976                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16977                        conn.provider.name);
16978            }
16979            app.conProviders.clear();
16980        }
16981
16982        // At this point there may be remaining entries in mLaunchingProviders
16983        // where we were the only one waiting, so they are no longer of use.
16984        // Look for these and clean up if found.
16985        // XXX Commented out for now.  Trying to figure out a way to reproduce
16986        // the actual situation to identify what is actually going on.
16987        if (false) {
16988            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16989                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16990                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16991                    synchronized (cpr) {
16992                        cpr.launchingApp = null;
16993                        cpr.notifyAll();
16994                    }
16995                }
16996            }
16997        }
16998
16999        skipCurrentReceiverLocked(app);
17000
17001        // Unregister any receivers.
17002        for (int i = app.receivers.size() - 1; i >= 0; i--) {
17003            removeReceiverLocked(app.receivers.valueAt(i));
17004        }
17005        app.receivers.clear();
17006
17007        // If the app is undergoing backup, tell the backup manager about it
17008        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
17009            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
17010                    + mBackupTarget.appInfo + " died during backup");
17011            mHandler.post(new Runnable() {
17012                @Override
17013                public void run(){
17014                    try {
17015                        IBackupManager bm = IBackupManager.Stub.asInterface(
17016                                ServiceManager.getService(Context.BACKUP_SERVICE));
17017                        bm.agentDisconnected(app.info.packageName);
17018                    } catch (RemoteException e) {
17019                        // can't happen; backup manager is local
17020                    }
17021                }
17022            });
17023        }
17024
17025        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
17026            ProcessChangeItem item = mPendingProcessChanges.get(i);
17027            if (item.pid == app.pid) {
17028                mPendingProcessChanges.remove(i);
17029                mAvailProcessChanges.add(item);
17030            }
17031        }
17032        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
17033                null).sendToTarget();
17034
17035        // If the caller is restarting this app, then leave it in its
17036        // current lists and let the caller take care of it.
17037        if (restarting) {
17038            return false;
17039        }
17040
17041        if (!app.persistent || app.isolated) {
17042            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
17043                    "Removing non-persistent process during cleanup: " + app);
17044            if (!replacingPid) {
17045                removeProcessNameLocked(app.processName, app.uid);
17046            }
17047            if (mHeavyWeightProcess == app) {
17048                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
17049                        mHeavyWeightProcess.userId, 0));
17050                mHeavyWeightProcess = null;
17051            }
17052        } else if (!app.removed) {
17053            // This app is persistent, so we need to keep its record around.
17054            // If it is not already on the pending app list, add it there
17055            // and start a new process for it.
17056            if (mPersistentStartingProcesses.indexOf(app) < 0) {
17057                mPersistentStartingProcesses.add(app);
17058                restart = true;
17059            }
17060        }
17061        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
17062                TAG_CLEANUP, "Clean-up removing on hold: " + app);
17063        mProcessesOnHold.remove(app);
17064
17065        if (app == mHomeProcess) {
17066            mHomeProcess = null;
17067        }
17068        if (app == mPreviousProcess) {
17069            mPreviousProcess = null;
17070        }
17071
17072        if (restart && !app.isolated) {
17073            // We have components that still need to be running in the
17074            // process, so re-launch it.
17075            if (index < 0) {
17076                ProcessList.remove(app.pid);
17077            }
17078            addProcessNameLocked(app);
17079            startProcessLocked(app, "restart", app.processName);
17080            return true;
17081        } else if (app.pid > 0 && app.pid != MY_PID) {
17082            // Goodbye!
17083            boolean removed;
17084            synchronized (mPidsSelfLocked) {
17085                mPidsSelfLocked.remove(app.pid);
17086                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
17087            }
17088            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
17089            if (app.isolated) {
17090                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
17091            }
17092            app.setPid(0);
17093        }
17094        return false;
17095    }
17096
17097    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
17098        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17099            ContentProviderRecord cpr = mLaunchingProviders.get(i);
17100            if (cpr.launchingApp == app) {
17101                return true;
17102            }
17103        }
17104        return false;
17105    }
17106
17107    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
17108        // Look through the content providers we are waiting to have launched,
17109        // and if any run in this process then either schedule a restart of
17110        // the process or kill the client waiting for it if this process has
17111        // gone bad.
17112        boolean restart = false;
17113        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17114            ContentProviderRecord cpr = mLaunchingProviders.get(i);
17115            if (cpr.launchingApp == app) {
17116                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
17117                    restart = true;
17118                } else {
17119                    removeDyingProviderLocked(app, cpr, true);
17120                }
17121            }
17122        }
17123        return restart;
17124    }
17125
17126    // =========================================================
17127    // SERVICES
17128    // =========================================================
17129
17130    @Override
17131    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
17132            int flags) {
17133        enforceNotIsolatedCaller("getServices");
17134        synchronized (this) {
17135            return mServices.getRunningServiceInfoLocked(maxNum, flags);
17136        }
17137    }
17138
17139    @Override
17140    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
17141        enforceNotIsolatedCaller("getRunningServiceControlPanel");
17142        synchronized (this) {
17143            return mServices.getRunningServiceControlPanelLocked(name);
17144        }
17145    }
17146
17147    @Override
17148    public ComponentName startService(IApplicationThread caller, Intent service,
17149            String resolvedType, String callingPackage, int userId)
17150            throws TransactionTooLargeException {
17151        enforceNotIsolatedCaller("startService");
17152        // Refuse possible leaked file descriptors
17153        if (service != null && service.hasFileDescriptors() == true) {
17154            throw new IllegalArgumentException("File descriptors passed in Intent");
17155        }
17156
17157        if (callingPackage == null) {
17158            throw new IllegalArgumentException("callingPackage cannot be null");
17159        }
17160
17161        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17162                "startService: " + service + " type=" + resolvedType);
17163        synchronized(this) {
17164            final int callingPid = Binder.getCallingPid();
17165            final int callingUid = Binder.getCallingUid();
17166            final long origId = Binder.clearCallingIdentity();
17167            ComponentName res = mServices.startServiceLocked(caller, service,
17168                    resolvedType, callingPid, callingUid, callingPackage, userId);
17169            Binder.restoreCallingIdentity(origId);
17170            return res;
17171        }
17172    }
17173
17174    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
17175            String callingPackage, int userId)
17176            throws TransactionTooLargeException {
17177        synchronized(this) {
17178            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17179                    "startServiceInPackage: " + service + " type=" + resolvedType);
17180            final long origId = Binder.clearCallingIdentity();
17181            ComponentName res = mServices.startServiceLocked(null, service,
17182                    resolvedType, -1, uid, callingPackage, userId);
17183            Binder.restoreCallingIdentity(origId);
17184            return res;
17185        }
17186    }
17187
17188    @Override
17189    public int stopService(IApplicationThread caller, Intent service,
17190            String resolvedType, int userId) {
17191        enforceNotIsolatedCaller("stopService");
17192        // Refuse possible leaked file descriptors
17193        if (service != null && service.hasFileDescriptors() == true) {
17194            throw new IllegalArgumentException("File descriptors passed in Intent");
17195        }
17196
17197        synchronized(this) {
17198            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
17199        }
17200    }
17201
17202    @Override
17203    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
17204        enforceNotIsolatedCaller("peekService");
17205        // Refuse possible leaked file descriptors
17206        if (service != null && service.hasFileDescriptors() == true) {
17207            throw new IllegalArgumentException("File descriptors passed in Intent");
17208        }
17209
17210        if (callingPackage == null) {
17211            throw new IllegalArgumentException("callingPackage cannot be null");
17212        }
17213
17214        synchronized(this) {
17215            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
17216        }
17217    }
17218
17219    @Override
17220    public boolean stopServiceToken(ComponentName className, IBinder token,
17221            int startId) {
17222        synchronized(this) {
17223            return mServices.stopServiceTokenLocked(className, token, startId);
17224        }
17225    }
17226
17227    @Override
17228    public void setServiceForeground(ComponentName className, IBinder token,
17229            int id, Notification notification, int flags) {
17230        synchronized(this) {
17231            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
17232        }
17233    }
17234
17235    @Override
17236    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
17237            boolean requireFull, String name, String callerPackage) {
17238        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
17239                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
17240    }
17241
17242    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
17243            String className, int flags) {
17244        boolean result = false;
17245        // For apps that don't have pre-defined UIDs, check for permission
17246        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
17247            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17248                if (ActivityManager.checkUidPermission(
17249                        INTERACT_ACROSS_USERS,
17250                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
17251                    ComponentName comp = new ComponentName(aInfo.packageName, className);
17252                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
17253                            + " requests FLAG_SINGLE_USER, but app does not hold "
17254                            + INTERACT_ACROSS_USERS;
17255                    Slog.w(TAG, msg);
17256                    throw new SecurityException(msg);
17257                }
17258                // Permission passed
17259                result = true;
17260            }
17261        } else if ("system".equals(componentProcessName)) {
17262            result = true;
17263        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17264            // Phone app and persistent apps are allowed to export singleuser providers.
17265            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
17266                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
17267        }
17268        if (DEBUG_MU) Slog.v(TAG_MU,
17269                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
17270                + Integer.toHexString(flags) + ") = " + result);
17271        return result;
17272    }
17273
17274    /**
17275     * Checks to see if the caller is in the same app as the singleton
17276     * component, or the component is in a special app. It allows special apps
17277     * to export singleton components but prevents exporting singleton
17278     * components for regular apps.
17279     */
17280    boolean isValidSingletonCall(int callingUid, int componentUid) {
17281        int componentAppId = UserHandle.getAppId(componentUid);
17282        return UserHandle.isSameApp(callingUid, componentUid)
17283                || componentAppId == Process.SYSTEM_UID
17284                || componentAppId == Process.PHONE_UID
17285                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
17286                        == PackageManager.PERMISSION_GRANTED;
17287    }
17288
17289    public int bindService(IApplicationThread caller, IBinder token, Intent service,
17290            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
17291            int userId) throws TransactionTooLargeException {
17292        enforceNotIsolatedCaller("bindService");
17293
17294        // Refuse possible leaked file descriptors
17295        if (service != null && service.hasFileDescriptors() == true) {
17296            throw new IllegalArgumentException("File descriptors passed in Intent");
17297        }
17298
17299        if (callingPackage == null) {
17300            throw new IllegalArgumentException("callingPackage cannot be null");
17301        }
17302
17303        synchronized(this) {
17304            return mServices.bindServiceLocked(caller, token, service,
17305                    resolvedType, connection, flags, callingPackage, userId);
17306        }
17307    }
17308
17309    public boolean unbindService(IServiceConnection connection) {
17310        synchronized (this) {
17311            return mServices.unbindServiceLocked(connection);
17312        }
17313    }
17314
17315    public void publishService(IBinder token, Intent intent, IBinder service) {
17316        // Refuse possible leaked file descriptors
17317        if (intent != null && intent.hasFileDescriptors() == true) {
17318            throw new IllegalArgumentException("File descriptors passed in Intent");
17319        }
17320
17321        synchronized(this) {
17322            if (!(token instanceof ServiceRecord)) {
17323                throw new IllegalArgumentException("Invalid service token");
17324            }
17325            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
17326        }
17327    }
17328
17329    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
17330        // Refuse possible leaked file descriptors
17331        if (intent != null && intent.hasFileDescriptors() == true) {
17332            throw new IllegalArgumentException("File descriptors passed in Intent");
17333        }
17334
17335        synchronized(this) {
17336            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
17337        }
17338    }
17339
17340    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
17341        synchronized(this) {
17342            if (!(token instanceof ServiceRecord)) {
17343                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
17344                throw new IllegalArgumentException("Invalid service token");
17345            }
17346            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
17347        }
17348    }
17349
17350    // =========================================================
17351    // BACKUP AND RESTORE
17352    // =========================================================
17353
17354    // Cause the target app to be launched if necessary and its backup agent
17355    // instantiated.  The backup agent will invoke backupAgentCreated() on the
17356    // activity manager to announce its creation.
17357    public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
17358        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
17359        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
17360
17361        IPackageManager pm = AppGlobals.getPackageManager();
17362        ApplicationInfo app = null;
17363        try {
17364            app = pm.getApplicationInfo(packageName, 0, userId);
17365        } catch (RemoteException e) {
17366            // can't happen; package manager is process-local
17367        }
17368        if (app == null) {
17369            Slog.w(TAG, "Unable to bind backup agent for " + packageName);
17370            return false;
17371        }
17372
17373        synchronized(this) {
17374            // !!! TODO: currently no check here that we're already bound
17375            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
17376            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17377            synchronized (stats) {
17378                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
17379            }
17380
17381            // Backup agent is now in use, its package can't be stopped.
17382            try {
17383                AppGlobals.getPackageManager().setPackageStoppedState(
17384                        app.packageName, false, UserHandle.getUserId(app.uid));
17385            } catch (RemoteException e) {
17386            } catch (IllegalArgumentException e) {
17387                Slog.w(TAG, "Failed trying to unstop package "
17388                        + app.packageName + ": " + e);
17389            }
17390
17391            BackupRecord r = new BackupRecord(ss, app, backupMode);
17392            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
17393                    ? new ComponentName(app.packageName, app.backupAgentName)
17394                    : new ComponentName("android", "FullBackupAgent");
17395            // startProcessLocked() returns existing proc's record if it's already running
17396            ProcessRecord proc = startProcessLocked(app.processName, app,
17397                    false, 0, "backup", hostingName, false, false, false);
17398            if (proc == null) {
17399                Slog.e(TAG, "Unable to start backup agent process " + r);
17400                return false;
17401            }
17402
17403            // If the app is a regular app (uid >= 10000) and not the system server or phone
17404            // process, etc, then mark it as being in full backup so that certain calls to the
17405            // process can be blocked. This is not reset to false anywhere because we kill the
17406            // process after the full backup is done and the ProcessRecord will vaporize anyway.
17407            if (UserHandle.isApp(app.uid) && backupMode == IApplicationThread.BACKUP_MODE_FULL) {
17408                proc.inFullBackup = true;
17409            }
17410            r.app = proc;
17411            mBackupTarget = r;
17412            mBackupAppName = app.packageName;
17413
17414            // Try not to kill the process during backup
17415            updateOomAdjLocked(proc);
17416
17417            // If the process is already attached, schedule the creation of the backup agent now.
17418            // If it is not yet live, this will be done when it attaches to the framework.
17419            if (proc.thread != null) {
17420                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
17421                try {
17422                    proc.thread.scheduleCreateBackupAgent(app,
17423                            compatibilityInfoForPackageLocked(app), backupMode);
17424                } catch (RemoteException e) {
17425                    // Will time out on the backup manager side
17426                }
17427            } else {
17428                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
17429            }
17430            // Invariants: at this point, the target app process exists and the application
17431            // is either already running or in the process of coming up.  mBackupTarget and
17432            // mBackupAppName describe the app, so that when it binds back to the AM we
17433            // know that it's scheduled for a backup-agent operation.
17434        }
17435
17436        return true;
17437    }
17438
17439    @Override
17440    public void clearPendingBackup() {
17441        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
17442        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
17443
17444        synchronized (this) {
17445            mBackupTarget = null;
17446            mBackupAppName = null;
17447        }
17448    }
17449
17450    // A backup agent has just come up
17451    public void backupAgentCreated(String agentPackageName, IBinder agent) {
17452        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
17453                + " = " + agent);
17454
17455        synchronized(this) {
17456            if (!agentPackageName.equals(mBackupAppName)) {
17457                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
17458                return;
17459            }
17460        }
17461
17462        long oldIdent = Binder.clearCallingIdentity();
17463        try {
17464            IBackupManager bm = IBackupManager.Stub.asInterface(
17465                    ServiceManager.getService(Context.BACKUP_SERVICE));
17466            bm.agentConnected(agentPackageName, agent);
17467        } catch (RemoteException e) {
17468            // can't happen; the backup manager service is local
17469        } catch (Exception e) {
17470            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
17471            e.printStackTrace();
17472        } finally {
17473            Binder.restoreCallingIdentity(oldIdent);
17474        }
17475    }
17476
17477    // done with this agent
17478    public void unbindBackupAgent(ApplicationInfo appInfo) {
17479        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
17480        if (appInfo == null) {
17481            Slog.w(TAG, "unbind backup agent for null app");
17482            return;
17483        }
17484
17485        synchronized(this) {
17486            try {
17487                if (mBackupAppName == null) {
17488                    Slog.w(TAG, "Unbinding backup agent with no active backup");
17489                    return;
17490                }
17491
17492                if (!mBackupAppName.equals(appInfo.packageName)) {
17493                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
17494                    return;
17495                }
17496
17497                // Not backing this app up any more; reset its OOM adjustment
17498                final ProcessRecord proc = mBackupTarget.app;
17499                updateOomAdjLocked(proc);
17500                proc.inFullBackup = false;
17501
17502                // If the app crashed during backup, 'thread' will be null here
17503                if (proc.thread != null) {
17504                    try {
17505                        proc.thread.scheduleDestroyBackupAgent(appInfo,
17506                                compatibilityInfoForPackageLocked(appInfo));
17507                    } catch (Exception e) {
17508                        Slog.e(TAG, "Exception when unbinding backup agent:");
17509                        e.printStackTrace();
17510                    }
17511                }
17512            } finally {
17513                mBackupTarget = null;
17514                mBackupAppName = null;
17515            }
17516        }
17517    }
17518    // =========================================================
17519    // BROADCASTS
17520    // =========================================================
17521
17522    boolean isPendingBroadcastProcessLocked(int pid) {
17523        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
17524                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
17525    }
17526
17527    void skipPendingBroadcastLocked(int pid) {
17528            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
17529            for (BroadcastQueue queue : mBroadcastQueues) {
17530                queue.skipPendingBroadcastLocked(pid);
17531            }
17532    }
17533
17534    // The app just attached; send any pending broadcasts that it should receive
17535    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
17536        boolean didSomething = false;
17537        for (BroadcastQueue queue : mBroadcastQueues) {
17538            didSomething |= queue.sendPendingBroadcastsLocked(app);
17539        }
17540        return didSomething;
17541    }
17542
17543    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
17544            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17545        enforceNotIsolatedCaller("registerReceiver");
17546        ArrayList<Intent> stickyIntents = null;
17547        ProcessRecord callerApp = null;
17548        int callingUid;
17549        int callingPid;
17550        synchronized(this) {
17551            if (caller != null) {
17552                callerApp = getRecordForAppLocked(caller);
17553                if (callerApp == null) {
17554                    throw new SecurityException(
17555                            "Unable to find app for caller " + caller
17556                            + " (pid=" + Binder.getCallingPid()
17557                            + ") when registering receiver " + receiver);
17558                }
17559                if (callerApp.info.uid != Process.SYSTEM_UID &&
17560                        !callerApp.pkgList.containsKey(callerPackage) &&
17561                        !"android".equals(callerPackage)) {
17562                    throw new SecurityException("Given caller package " + callerPackage
17563                            + " is not running in process " + callerApp);
17564                }
17565                callingUid = callerApp.info.uid;
17566                callingPid = callerApp.pid;
17567            } else {
17568                callerPackage = null;
17569                callingUid = Binder.getCallingUid();
17570                callingPid = Binder.getCallingPid();
17571            }
17572
17573            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17574                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17575
17576            Iterator<String> actions = filter.actionsIterator();
17577            if (actions == null) {
17578                ArrayList<String> noAction = new ArrayList<String>(1);
17579                noAction.add(null);
17580                actions = noAction.iterator();
17581            }
17582
17583            // Collect stickies of users
17584            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17585            while (actions.hasNext()) {
17586                String action = actions.next();
17587                for (int id : userIds) {
17588                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17589                    if (stickies != null) {
17590                        ArrayList<Intent> intents = stickies.get(action);
17591                        if (intents != null) {
17592                            if (stickyIntents == null) {
17593                                stickyIntents = new ArrayList<Intent>();
17594                            }
17595                            stickyIntents.addAll(intents);
17596                        }
17597                    }
17598                }
17599            }
17600        }
17601
17602        ArrayList<Intent> allSticky = null;
17603        if (stickyIntents != null) {
17604            final ContentResolver resolver = mContext.getContentResolver();
17605            // Look for any matching sticky broadcasts...
17606            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17607                Intent intent = stickyIntents.get(i);
17608                // If intent has scheme "content", it will need to acccess
17609                // provider that needs to lock mProviderMap in ActivityThread
17610                // and also it may need to wait application response, so we
17611                // cannot lock ActivityManagerService here.
17612                if (filter.match(resolver, intent, true, TAG) >= 0) {
17613                    if (allSticky == null) {
17614                        allSticky = new ArrayList<Intent>();
17615                    }
17616                    allSticky.add(intent);
17617                }
17618            }
17619        }
17620
17621        // The first sticky in the list is returned directly back to the client.
17622        Intent sticky = allSticky != null ? allSticky.get(0) : null;
17623        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17624        if (receiver == null) {
17625            return sticky;
17626        }
17627
17628        synchronized (this) {
17629            if (callerApp != null && (callerApp.thread == null
17630                    || callerApp.thread.asBinder() != caller.asBinder())) {
17631                // Original caller already died
17632                return null;
17633            }
17634            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17635            if (rl == null) {
17636                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17637                        userId, receiver);
17638                if (rl.app != null) {
17639                    rl.app.receivers.add(rl);
17640                } else {
17641                    try {
17642                        receiver.asBinder().linkToDeath(rl, 0);
17643                    } catch (RemoteException e) {
17644                        return sticky;
17645                    }
17646                    rl.linkedToDeath = true;
17647                }
17648                mRegisteredReceivers.put(receiver.asBinder(), rl);
17649            } else if (rl.uid != callingUid) {
17650                throw new IllegalArgumentException(
17651                        "Receiver requested to register for uid " + callingUid
17652                        + " was previously registered for uid " + rl.uid);
17653            } else if (rl.pid != callingPid) {
17654                throw new IllegalArgumentException(
17655                        "Receiver requested to register for pid " + callingPid
17656                        + " was previously registered for pid " + rl.pid);
17657            } else if (rl.userId != userId) {
17658                throw new IllegalArgumentException(
17659                        "Receiver requested to register for user " + userId
17660                        + " was previously registered for user " + rl.userId);
17661            }
17662            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17663                    permission, callingUid, userId);
17664            rl.add(bf);
17665            if (!bf.debugCheck()) {
17666                Slog.w(TAG, "==> For Dynamic broadcast");
17667            }
17668            mReceiverResolver.addFilter(bf);
17669
17670            // Enqueue broadcasts for all existing stickies that match
17671            // this filter.
17672            if (allSticky != null) {
17673                ArrayList receivers = new ArrayList();
17674                receivers.add(bf);
17675
17676                final int stickyCount = allSticky.size();
17677                for (int i = 0; i < stickyCount; i++) {
17678                    Intent intent = allSticky.get(i);
17679                    BroadcastQueue queue = broadcastQueueForIntent(intent);
17680                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17681                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17682                            null, 0, null, null, false, true, true, -1);
17683                    queue.enqueueParallelBroadcastLocked(r);
17684                    queue.scheduleBroadcastsLocked();
17685                }
17686            }
17687
17688            return sticky;
17689        }
17690    }
17691
17692    public void unregisterReceiver(IIntentReceiver receiver) {
17693        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17694
17695        final long origId = Binder.clearCallingIdentity();
17696        try {
17697            boolean doTrim = false;
17698
17699            synchronized(this) {
17700                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17701                if (rl != null) {
17702                    final BroadcastRecord r = rl.curBroadcast;
17703                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17704                        final boolean doNext = r.queue.finishReceiverLocked(
17705                                r, r.resultCode, r.resultData, r.resultExtras,
17706                                r.resultAbort, false);
17707                        if (doNext) {
17708                            doTrim = true;
17709                            r.queue.processNextBroadcast(false);
17710                        }
17711                    }
17712
17713                    if (rl.app != null) {
17714                        rl.app.receivers.remove(rl);
17715                    }
17716                    removeReceiverLocked(rl);
17717                    if (rl.linkedToDeath) {
17718                        rl.linkedToDeath = false;
17719                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
17720                    }
17721                }
17722            }
17723
17724            // If we actually concluded any broadcasts, we might now be able
17725            // to trim the recipients' apps from our working set
17726            if (doTrim) {
17727                trimApplications();
17728                return;
17729            }
17730
17731        } finally {
17732            Binder.restoreCallingIdentity(origId);
17733        }
17734    }
17735
17736    void removeReceiverLocked(ReceiverList rl) {
17737        mRegisteredReceivers.remove(rl.receiver.asBinder());
17738        for (int i = rl.size() - 1; i >= 0; i--) {
17739            mReceiverResolver.removeFilter(rl.get(i));
17740        }
17741    }
17742
17743    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17744        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17745            ProcessRecord r = mLruProcesses.get(i);
17746            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17747                try {
17748                    r.thread.dispatchPackageBroadcast(cmd, packages);
17749                } catch (RemoteException ex) {
17750                }
17751            }
17752        }
17753    }
17754
17755    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17756            int callingUid, int[] users) {
17757        // TODO: come back and remove this assumption to triage all broadcasts
17758        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17759
17760        List<ResolveInfo> receivers = null;
17761        try {
17762            HashSet<ComponentName> singleUserReceivers = null;
17763            boolean scannedFirstReceivers = false;
17764            for (int user : users) {
17765                // Skip users that have Shell restrictions, with exception of always permitted
17766                // Shell broadcasts
17767                if (callingUid == Process.SHELL_UID
17768                        && mUserController.hasUserRestriction(
17769                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17770                        && !isPermittedShellBroadcast(intent)) {
17771                    continue;
17772                }
17773                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17774                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17775                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17776                    // If this is not the system user, we need to check for
17777                    // any receivers that should be filtered out.
17778                    for (int i=0; i<newReceivers.size(); i++) {
17779                        ResolveInfo ri = newReceivers.get(i);
17780                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17781                            newReceivers.remove(i);
17782                            i--;
17783                        }
17784                    }
17785                }
17786                if (newReceivers != null && newReceivers.size() == 0) {
17787                    newReceivers = null;
17788                }
17789                if (receivers == null) {
17790                    receivers = newReceivers;
17791                } else if (newReceivers != null) {
17792                    // We need to concatenate the additional receivers
17793                    // found with what we have do far.  This would be easy,
17794                    // but we also need to de-dup any receivers that are
17795                    // singleUser.
17796                    if (!scannedFirstReceivers) {
17797                        // Collect any single user receivers we had already retrieved.
17798                        scannedFirstReceivers = true;
17799                        for (int i=0; i<receivers.size(); i++) {
17800                            ResolveInfo ri = receivers.get(i);
17801                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17802                                ComponentName cn = new ComponentName(
17803                                        ri.activityInfo.packageName, ri.activityInfo.name);
17804                                if (singleUserReceivers == null) {
17805                                    singleUserReceivers = new HashSet<ComponentName>();
17806                                }
17807                                singleUserReceivers.add(cn);
17808                            }
17809                        }
17810                    }
17811                    // Add the new results to the existing results, tracking
17812                    // and de-dupping single user receivers.
17813                    for (int i=0; i<newReceivers.size(); i++) {
17814                        ResolveInfo ri = newReceivers.get(i);
17815                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17816                            ComponentName cn = new ComponentName(
17817                                    ri.activityInfo.packageName, ri.activityInfo.name);
17818                            if (singleUserReceivers == null) {
17819                                singleUserReceivers = new HashSet<ComponentName>();
17820                            }
17821                            if (!singleUserReceivers.contains(cn)) {
17822                                singleUserReceivers.add(cn);
17823                                receivers.add(ri);
17824                            }
17825                        } else {
17826                            receivers.add(ri);
17827                        }
17828                    }
17829                }
17830            }
17831        } catch (RemoteException ex) {
17832            // pm is in same process, this will never happen.
17833        }
17834        return receivers;
17835    }
17836
17837    private boolean isPermittedShellBroadcast(Intent intent) {
17838        // remote bugreport should always be allowed to be taken
17839        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17840    }
17841
17842    private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
17843            String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
17844        final String action = intent.getAction();
17845        if (isProtectedBroadcast
17846                || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17847                || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17848                || Intent.ACTION_MEDIA_BUTTON.equals(action)
17849                || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17850                || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17851                || Intent.ACTION_MASTER_CLEAR.equals(action)
17852                || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17853                || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17854                || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
17855                || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
17856                || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
17857            // Broadcast is either protected, or it's a public action that
17858            // we've relaxed, so it's fine for system internals to send.
17859            return;
17860        }
17861
17862        // This broadcast may be a problem...  but there are often system components that
17863        // want to send an internal broadcast to themselves, which is annoying to have to
17864        // explicitly list each action as a protected broadcast, so we will check for that
17865        // one safe case and allow it: an explicit broadcast, only being received by something
17866        // that has protected itself.
17867        if (receivers != null && receivers.size() > 0
17868                && (intent.getPackage() != null || intent.getComponent() != null)) {
17869            boolean allProtected = true;
17870            for (int i = receivers.size()-1; i >= 0; i--) {
17871                Object target = receivers.get(i);
17872                if (target instanceof ResolveInfo) {
17873                    ResolveInfo ri = (ResolveInfo)target;
17874                    if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
17875                        allProtected = false;
17876                        break;
17877                    }
17878                } else {
17879                    BroadcastFilter bf = (BroadcastFilter)target;
17880                    if (bf.requiredPermission == null) {
17881                        allProtected = false;
17882                        break;
17883                    }
17884                }
17885            }
17886            if (allProtected) {
17887                // All safe!
17888                return;
17889            }
17890        }
17891
17892        // The vast majority of broadcasts sent from system internals
17893        // should be protected to avoid security holes, so yell loudly
17894        // to ensure we examine these cases.
17895        if (callerApp != null) {
17896            Log.wtf(TAG, "Sending non-protected broadcast " + action
17897                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
17898                    new Throwable());
17899        } else {
17900            Log.wtf(TAG, "Sending non-protected broadcast " + action
17901                            + " from system uid " + UserHandle.formatUid(callingUid)
17902                            + " pkg " + callerPackage,
17903                    new Throwable());
17904        }
17905    }
17906
17907    final int broadcastIntentLocked(ProcessRecord callerApp,
17908            String callerPackage, Intent intent, String resolvedType,
17909            IIntentReceiver resultTo, int resultCode, String resultData,
17910            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17911            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17912        intent = new Intent(intent);
17913
17914        // By default broadcasts do not go to stopped apps.
17915        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17916
17917        // If we have not finished booting, don't allow this to launch new processes.
17918        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17919            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17920        }
17921
17922        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17923                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17924                + " ordered=" + ordered + " userid=" + userId);
17925        if ((resultTo != null) && !ordered) {
17926            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17927        }
17928
17929        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17930                ALLOW_NON_FULL, "broadcast", callerPackage);
17931
17932        // Make sure that the user who is receiving this broadcast is running.
17933        // If not, we will just skip it. Make an exception for shutdown broadcasts
17934        // and upgrade steps.
17935
17936        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17937            if ((callingUid != Process.SYSTEM_UID
17938                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17939                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17940                Slog.w(TAG, "Skipping broadcast of " + intent
17941                        + ": user " + userId + " is stopped");
17942                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17943            }
17944        }
17945
17946        BroadcastOptions brOptions = null;
17947        if (bOptions != null) {
17948            brOptions = new BroadcastOptions(bOptions);
17949            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17950                // See if the caller is allowed to do this.  Note we are checking against
17951                // the actual real caller (not whoever provided the operation as say a
17952                // PendingIntent), because that who is actually supplied the arguments.
17953                if (checkComponentPermission(
17954                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17955                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17956                        != PackageManager.PERMISSION_GRANTED) {
17957                    String msg = "Permission Denial: " + intent.getAction()
17958                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17959                            + ", uid=" + callingUid + ")"
17960                            + " requires "
17961                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17962                    Slog.w(TAG, msg);
17963                    throw new SecurityException(msg);
17964                }
17965            }
17966        }
17967
17968        // Verify that protected broadcasts are only being sent by system code,
17969        // and that system code is only sending protected broadcasts.
17970        final String action = intent.getAction();
17971        final boolean isProtectedBroadcast;
17972        try {
17973            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17974        } catch (RemoteException e) {
17975            Slog.w(TAG, "Remote exception", e);
17976            return ActivityManager.BROADCAST_SUCCESS;
17977        }
17978
17979        final boolean isCallerSystem;
17980        switch (UserHandle.getAppId(callingUid)) {
17981            case Process.ROOT_UID:
17982            case Process.SYSTEM_UID:
17983            case Process.PHONE_UID:
17984            case Process.BLUETOOTH_UID:
17985            case Process.NFC_UID:
17986                isCallerSystem = true;
17987                break;
17988            default:
17989                isCallerSystem = (callerApp != null) && callerApp.persistent;
17990                break;
17991        }
17992
17993        // First line security check before anything else: stop non-system apps from
17994        // sending protected broadcasts.
17995        if (!isCallerSystem) {
17996            if (isProtectedBroadcast) {
17997                String msg = "Permission Denial: not allowed to send broadcast "
17998                        + action + " from pid="
17999                        + callingPid + ", uid=" + callingUid;
18000                Slog.w(TAG, msg);
18001                throw new SecurityException(msg);
18002
18003            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
18004                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
18005                // Special case for compatibility: we don't want apps to send this,
18006                // but historically it has not been protected and apps may be using it
18007                // to poke their own app widget.  So, instead of making it protected,
18008                // just limit it to the caller.
18009                if (callerPackage == null) {
18010                    String msg = "Permission Denial: not allowed to send broadcast "
18011                            + action + " from unknown caller.";
18012                    Slog.w(TAG, msg);
18013                    throw new SecurityException(msg);
18014                } else if (intent.getComponent() != null) {
18015                    // They are good enough to send to an explicit component...  verify
18016                    // it is being sent to the calling app.
18017                    if (!intent.getComponent().getPackageName().equals(
18018                            callerPackage)) {
18019                        String msg = "Permission Denial: not allowed to send broadcast "
18020                                + action + " to "
18021                                + intent.getComponent().getPackageName() + " from "
18022                                + callerPackage;
18023                        Slog.w(TAG, msg);
18024                        throw new SecurityException(msg);
18025                    }
18026                } else {
18027                    // Limit broadcast to their own package.
18028                    intent.setPackage(callerPackage);
18029                }
18030            }
18031        }
18032
18033        if (action != null) {
18034            switch (action) {
18035                case Intent.ACTION_UID_REMOVED:
18036                case Intent.ACTION_PACKAGE_REMOVED:
18037                case Intent.ACTION_PACKAGE_CHANGED:
18038                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
18039                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
18040                case Intent.ACTION_PACKAGES_SUSPENDED:
18041                case Intent.ACTION_PACKAGES_UNSUSPENDED:
18042                    // Handle special intents: if this broadcast is from the package
18043                    // manager about a package being removed, we need to remove all of
18044                    // its activities from the history stack.
18045                    if (checkComponentPermission(
18046                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
18047                            callingPid, callingUid, -1, true)
18048                            != PackageManager.PERMISSION_GRANTED) {
18049                        String msg = "Permission Denial: " + intent.getAction()
18050                                + " broadcast from " + callerPackage + " (pid=" + callingPid
18051                                + ", uid=" + callingUid + ")"
18052                                + " requires "
18053                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
18054                        Slog.w(TAG, msg);
18055                        throw new SecurityException(msg);
18056                    }
18057                    switch (action) {
18058                        case Intent.ACTION_UID_REMOVED:
18059                            final Bundle intentExtras = intent.getExtras();
18060                            final int uid = intentExtras != null
18061                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
18062                            if (uid >= 0) {
18063                                mBatteryStatsService.removeUid(uid);
18064                                mAppOpsService.uidRemoved(uid);
18065                            }
18066                            break;
18067                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
18068                            // If resources are unavailable just force stop all those packages
18069                            // and flush the attribute cache as well.
18070                            String list[] =
18071                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18072                            if (list != null && list.length > 0) {
18073                                for (int i = 0; i < list.length; i++) {
18074                                    forceStopPackageLocked(list[i], -1, false, true, true,
18075                                            false, false, userId, "storage unmount");
18076                                }
18077                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
18078                                sendPackageBroadcastLocked(
18079                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
18080                                        userId);
18081                            }
18082                            break;
18083                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
18084                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
18085                            break;
18086                        case Intent.ACTION_PACKAGE_REMOVED:
18087                        case Intent.ACTION_PACKAGE_CHANGED:
18088                            Uri data = intent.getData();
18089                            String ssp;
18090                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
18091                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
18092                                final boolean replacing =
18093                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
18094                                final boolean killProcess =
18095                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
18096                                final boolean fullUninstall = removed && !replacing;
18097                                if (removed) {
18098                                    if (killProcess) {
18099                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
18100                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
18101                                                false, true, true, false, fullUninstall, userId,
18102                                                removed ? "pkg removed" : "pkg changed");
18103                                    }
18104                                    final int cmd = killProcess
18105                                            ? IApplicationThread.PACKAGE_REMOVED
18106                                            : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
18107                                    sendPackageBroadcastLocked(cmd,
18108                                            new String[] {ssp}, userId);
18109                                    if (fullUninstall) {
18110                                        mAppOpsService.packageRemoved(
18111                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
18112
18113                                        // Remove all permissions granted from/to this package
18114                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
18115
18116                                        removeTasksByPackageNameLocked(ssp, userId);
18117
18118                                        // Hide the "unsupported display" dialog if necessary.
18119                                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
18120                                                mUnsupportedDisplaySizeDialog.getPackageName())) {
18121                                            mUnsupportedDisplaySizeDialog.dismiss();
18122                                            mUnsupportedDisplaySizeDialog = null;
18123                                        }
18124                                        mCompatModePackages.handlePackageUninstalledLocked(ssp);
18125                                        mBatteryStatsService.notePackageUninstalled(ssp);
18126                                    }
18127                                } else {
18128                                    if (killProcess) {
18129                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
18130                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
18131                                                userId, ProcessList.INVALID_ADJ,
18132                                                false, true, true, false, "change " + ssp);
18133                                    }
18134                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
18135                                            intent.getStringArrayExtra(
18136                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
18137                                }
18138                            }
18139                            break;
18140                        case Intent.ACTION_PACKAGES_SUSPENDED:
18141                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
18142                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
18143                                    intent.getAction());
18144                            final String[] packageNames = intent.getStringArrayExtra(
18145                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
18146                            final int userHandle = intent.getIntExtra(
18147                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
18148
18149                            synchronized(ActivityManagerService.this) {
18150                                mRecentTasks.onPackagesSuspendedChanged(
18151                                        packageNames, suspended, userHandle);
18152                            }
18153                            break;
18154                    }
18155                    break;
18156                case Intent.ACTION_PACKAGE_REPLACED:
18157                {
18158                    final Uri data = intent.getData();
18159                    final String ssp;
18160                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18161                        final ApplicationInfo aInfo =
18162                                getPackageManagerInternalLocked().getApplicationInfo(
18163                                        ssp,
18164                                        userId);
18165                        if (aInfo == null) {
18166                            Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
18167                                    + " ssp=" + ssp + " data=" + data);
18168                            return ActivityManager.BROADCAST_SUCCESS;
18169                        }
18170                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
18171                        sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
18172                                new String[] {ssp}, userId);
18173                    }
18174                    break;
18175                }
18176                case Intent.ACTION_PACKAGE_ADDED:
18177                {
18178                    // Special case for adding a package: by default turn on compatibility mode.
18179                    Uri data = intent.getData();
18180                    String ssp;
18181                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18182                        final boolean replacing =
18183                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
18184                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
18185
18186                        try {
18187                            ApplicationInfo ai = AppGlobals.getPackageManager().
18188                                    getApplicationInfo(ssp, 0, 0);
18189                            mBatteryStatsService.notePackageInstalled(ssp,
18190                                    ai != null ? ai.versionCode : 0);
18191                        } catch (RemoteException e) {
18192                        }
18193                    }
18194                    break;
18195                }
18196                case Intent.ACTION_PACKAGE_DATA_CLEARED:
18197                {
18198                    Uri data = intent.getData();
18199                    String ssp;
18200                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18201                        // Hide the "unsupported display" dialog if necessary.
18202                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
18203                                mUnsupportedDisplaySizeDialog.getPackageName())) {
18204                            mUnsupportedDisplaySizeDialog.dismiss();
18205                            mUnsupportedDisplaySizeDialog = null;
18206                        }
18207                        mCompatModePackages.handlePackageDataClearedLocked(ssp);
18208                    }
18209                    break;
18210                }
18211                case Intent.ACTION_TIMEZONE_CHANGED:
18212                    // If this is the time zone changed action, queue up a message that will reset
18213                    // the timezone of all currently running processes. This message will get
18214                    // queued up before the broadcast happens.
18215                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
18216                    break;
18217                case Intent.ACTION_TIME_CHANGED:
18218                    // If the user set the time, let all running processes know.
18219                    final int is24Hour =
18220                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
18221                                    : 0;
18222                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
18223                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18224                    synchronized (stats) {
18225                        stats.noteCurrentTimeChangedLocked();
18226                    }
18227                    break;
18228                case Intent.ACTION_CLEAR_DNS_CACHE:
18229                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
18230                    break;
18231                case Proxy.PROXY_CHANGE_ACTION:
18232                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
18233                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
18234                    break;
18235                case android.hardware.Camera.ACTION_NEW_PICTURE:
18236                case android.hardware.Camera.ACTION_NEW_VIDEO:
18237                    // These broadcasts are no longer allowed by the system, since they can
18238                    // cause significant thrashing at a crictical point (using the camera).
18239                    // Apps should use JobScehduler to monitor for media provider changes.
18240                    Slog.w(TAG, action + " no longer allowed; dropping from "
18241                            + UserHandle.formatUid(callingUid));
18242                    if (resultTo != null) {
18243                        final BroadcastQueue queue = broadcastQueueForIntent(intent);
18244                        try {
18245                            queue.performReceiveLocked(callerApp, resultTo, intent,
18246                                    Activity.RESULT_CANCELED, null, null,
18247                                    false, false, userId);
18248                        } catch (RemoteException e) {
18249                            Slog.w(TAG, "Failure ["
18250                                    + queue.mQueueName + "] sending broadcast result of "
18251                                    + intent, e);
18252
18253                        }
18254                    }
18255                    // Lie; we don't want to crash the app.
18256                    return ActivityManager.BROADCAST_SUCCESS;
18257            }
18258        }
18259
18260        // Add to the sticky list if requested.
18261        if (sticky) {
18262            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
18263                    callingPid, callingUid)
18264                    != PackageManager.PERMISSION_GRANTED) {
18265                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
18266                        + callingPid + ", uid=" + callingUid
18267                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18268                Slog.w(TAG, msg);
18269                throw new SecurityException(msg);
18270            }
18271            if (requiredPermissions != null && requiredPermissions.length > 0) {
18272                Slog.w(TAG, "Can't broadcast sticky intent " + intent
18273                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
18274                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
18275            }
18276            if (intent.getComponent() != null) {
18277                throw new SecurityException(
18278                        "Sticky broadcasts can't target a specific component");
18279            }
18280            // We use userId directly here, since the "all" target is maintained
18281            // as a separate set of sticky broadcasts.
18282            if (userId != UserHandle.USER_ALL) {
18283                // But first, if this is not a broadcast to all users, then
18284                // make sure it doesn't conflict with an existing broadcast to
18285                // all users.
18286                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
18287                        UserHandle.USER_ALL);
18288                if (stickies != null) {
18289                    ArrayList<Intent> list = stickies.get(intent.getAction());
18290                    if (list != null) {
18291                        int N = list.size();
18292                        int i;
18293                        for (i=0; i<N; i++) {
18294                            if (intent.filterEquals(list.get(i))) {
18295                                throw new IllegalArgumentException(
18296                                        "Sticky broadcast " + intent + " for user "
18297                                        + userId + " conflicts with existing global broadcast");
18298                            }
18299                        }
18300                    }
18301                }
18302            }
18303            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18304            if (stickies == null) {
18305                stickies = new ArrayMap<>();
18306                mStickyBroadcasts.put(userId, stickies);
18307            }
18308            ArrayList<Intent> list = stickies.get(intent.getAction());
18309            if (list == null) {
18310                list = new ArrayList<>();
18311                stickies.put(intent.getAction(), list);
18312            }
18313            final int stickiesCount = list.size();
18314            int i;
18315            for (i = 0; i < stickiesCount; i++) {
18316                if (intent.filterEquals(list.get(i))) {
18317                    // This sticky already exists, replace it.
18318                    list.set(i, new Intent(intent));
18319                    break;
18320                }
18321            }
18322            if (i >= stickiesCount) {
18323                list.add(new Intent(intent));
18324            }
18325        }
18326
18327        int[] users;
18328        if (userId == UserHandle.USER_ALL) {
18329            // Caller wants broadcast to go to all started users.
18330            users = mUserController.getStartedUserArrayLocked();
18331        } else {
18332            // Caller wants broadcast to go to one specific user.
18333            users = new int[] {userId};
18334        }
18335
18336        // Figure out who all will receive this broadcast.
18337        List receivers = null;
18338        List<BroadcastFilter> registeredReceivers = null;
18339        // Need to resolve the intent to interested receivers...
18340        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
18341                 == 0) {
18342            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
18343        }
18344        if (intent.getComponent() == null) {
18345            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
18346                // Query one target user at a time, excluding shell-restricted users
18347                for (int i = 0; i < users.length; i++) {
18348                    if (mUserController.hasUserRestriction(
18349                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
18350                        continue;
18351                    }
18352                    List<BroadcastFilter> registeredReceiversForUser =
18353                            mReceiverResolver.queryIntent(intent,
18354                                    resolvedType, false, users[i]);
18355                    if (registeredReceivers == null) {
18356                        registeredReceivers = registeredReceiversForUser;
18357                    } else if (registeredReceiversForUser != null) {
18358                        registeredReceivers.addAll(registeredReceiversForUser);
18359                    }
18360                }
18361            } else {
18362                registeredReceivers = mReceiverResolver.queryIntent(intent,
18363                        resolvedType, false, userId);
18364            }
18365        }
18366
18367        final boolean replacePending =
18368                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
18369
18370        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
18371                + " replacePending=" + replacePending);
18372
18373        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
18374        if (!ordered && NR > 0) {
18375            // If we are not serializing this broadcast, then send the
18376            // registered receivers separately so they don't wait for the
18377            // components to be launched.
18378            if (isCallerSystem) {
18379                checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
18380                        isProtectedBroadcast, registeredReceivers);
18381            }
18382            final BroadcastQueue queue = broadcastQueueForIntent(intent);
18383            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18384                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
18385                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
18386                    resultExtras, ordered, sticky, false, userId);
18387            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
18388            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
18389            if (!replaced) {
18390                queue.enqueueParallelBroadcastLocked(r);
18391                queue.scheduleBroadcastsLocked();
18392            }
18393            registeredReceivers = null;
18394            NR = 0;
18395        }
18396
18397        // Merge into one list.
18398        int ir = 0;
18399        if (receivers != null) {
18400            // A special case for PACKAGE_ADDED: do not allow the package
18401            // being added to see this broadcast.  This prevents them from
18402            // using this as a back door to get run as soon as they are
18403            // installed.  Maybe in the future we want to have a special install
18404            // broadcast or such for apps, but we'd like to deliberately make
18405            // this decision.
18406            String skipPackages[] = null;
18407            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
18408                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
18409                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
18410                Uri data = intent.getData();
18411                if (data != null) {
18412                    String pkgName = data.getSchemeSpecificPart();
18413                    if (pkgName != null) {
18414                        skipPackages = new String[] { pkgName };
18415                    }
18416                }
18417            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
18418                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18419            }
18420            if (skipPackages != null && (skipPackages.length > 0)) {
18421                for (String skipPackage : skipPackages) {
18422                    if (skipPackage != null) {
18423                        int NT = receivers.size();
18424                        for (int it=0; it<NT; it++) {
18425                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
18426                            if (curt.activityInfo.packageName.equals(skipPackage)) {
18427                                receivers.remove(it);
18428                                it--;
18429                                NT--;
18430                            }
18431                        }
18432                    }
18433                }
18434            }
18435
18436            int NT = receivers != null ? receivers.size() : 0;
18437            int it = 0;
18438            ResolveInfo curt = null;
18439            BroadcastFilter curr = null;
18440            while (it < NT && ir < NR) {
18441                if (curt == null) {
18442                    curt = (ResolveInfo)receivers.get(it);
18443                }
18444                if (curr == null) {
18445                    curr = registeredReceivers.get(ir);
18446                }
18447                if (curr.getPriority() >= curt.priority) {
18448                    // Insert this broadcast record into the final list.
18449                    receivers.add(it, curr);
18450                    ir++;
18451                    curr = null;
18452                    it++;
18453                    NT++;
18454                } else {
18455                    // Skip to the next ResolveInfo in the final list.
18456                    it++;
18457                    curt = null;
18458                }
18459            }
18460        }
18461        while (ir < NR) {
18462            if (receivers == null) {
18463                receivers = new ArrayList();
18464            }
18465            receivers.add(registeredReceivers.get(ir));
18466            ir++;
18467        }
18468
18469        if (isCallerSystem) {
18470            checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
18471                    isProtectedBroadcast, receivers);
18472        }
18473
18474        if ((receivers != null && receivers.size() > 0)
18475                || resultTo != null) {
18476            BroadcastQueue queue = broadcastQueueForIntent(intent);
18477            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18478                    callerPackage, callingPid, callingUid, resolvedType,
18479                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
18480                    resultData, resultExtras, ordered, sticky, false, userId);
18481
18482            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
18483                    + ": prev had " + queue.mOrderedBroadcasts.size());
18484            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
18485                    "Enqueueing broadcast " + r.intent.getAction());
18486
18487            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
18488            if (!replaced) {
18489                queue.enqueueOrderedBroadcastLocked(r);
18490                queue.scheduleBroadcastsLocked();
18491            }
18492        } else {
18493            // There was nobody interested in the broadcast, but we still want to record
18494            // that it happened.
18495            if (intent.getComponent() == null && intent.getPackage() == null
18496                    && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18497                // This was an implicit broadcast... let's record it for posterity.
18498                addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
18499            }
18500        }
18501
18502        return ActivityManager.BROADCAST_SUCCESS;
18503    }
18504
18505    final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
18506            int skipCount, long dispatchTime) {
18507        final long now = SystemClock.elapsedRealtime();
18508        if (mCurBroadcastStats == null ||
18509                (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
18510            mLastBroadcastStats = mCurBroadcastStats;
18511            if (mLastBroadcastStats != null) {
18512                mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
18513                mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
18514            }
18515            mCurBroadcastStats = new BroadcastStats();
18516        }
18517        mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
18518    }
18519
18520    final Intent verifyBroadcastLocked(Intent intent) {
18521        // Refuse possible leaked file descriptors
18522        if (intent != null && intent.hasFileDescriptors() == true) {
18523            throw new IllegalArgumentException("File descriptors passed in Intent");
18524        }
18525
18526        int flags = intent.getFlags();
18527
18528        if (!mProcessesReady) {
18529            // if the caller really truly claims to know what they're doing, go
18530            // ahead and allow the broadcast without launching any receivers
18531            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
18532                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
18533            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18534                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
18535                        + " before boot completion");
18536                throw new IllegalStateException("Cannot broadcast before boot completed");
18537            }
18538        }
18539
18540        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
18541            throw new IllegalArgumentException(
18542                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
18543        }
18544
18545        return intent;
18546    }
18547
18548    public final int broadcastIntent(IApplicationThread caller,
18549            Intent intent, String resolvedType, IIntentReceiver resultTo,
18550            int resultCode, String resultData, Bundle resultExtras,
18551            String[] requiredPermissions, int appOp, Bundle bOptions,
18552            boolean serialized, boolean sticky, int userId) {
18553        enforceNotIsolatedCaller("broadcastIntent");
18554        synchronized(this) {
18555            intent = verifyBroadcastLocked(intent);
18556
18557            final ProcessRecord callerApp = getRecordForAppLocked(caller);
18558            final int callingPid = Binder.getCallingPid();
18559            final int callingUid = Binder.getCallingUid();
18560            final long origId = Binder.clearCallingIdentity();
18561            int res = broadcastIntentLocked(callerApp,
18562                    callerApp != null ? callerApp.info.packageName : null,
18563                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
18564                    requiredPermissions, appOp, bOptions, serialized, sticky,
18565                    callingPid, callingUid, userId);
18566            Binder.restoreCallingIdentity(origId);
18567            return res;
18568        }
18569    }
18570
18571
18572    int broadcastIntentInPackage(String packageName, int uid,
18573            Intent intent, String resolvedType, IIntentReceiver resultTo,
18574            int resultCode, String resultData, Bundle resultExtras,
18575            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
18576            int userId) {
18577        synchronized(this) {
18578            intent = verifyBroadcastLocked(intent);
18579
18580            final long origId = Binder.clearCallingIdentity();
18581            String[] requiredPermissions = requiredPermission == null ? null
18582                    : new String[] {requiredPermission};
18583            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
18584                    resultTo, resultCode, resultData, resultExtras,
18585                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
18586                    sticky, -1, uid, userId);
18587            Binder.restoreCallingIdentity(origId);
18588            return res;
18589        }
18590    }
18591
18592    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
18593        // Refuse possible leaked file descriptors
18594        if (intent != null && intent.hasFileDescriptors() == true) {
18595            throw new IllegalArgumentException("File descriptors passed in Intent");
18596        }
18597
18598        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18599                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
18600
18601        synchronized(this) {
18602            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
18603                    != PackageManager.PERMISSION_GRANTED) {
18604                String msg = "Permission Denial: unbroadcastIntent() from pid="
18605                        + Binder.getCallingPid()
18606                        + ", uid=" + Binder.getCallingUid()
18607                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18608                Slog.w(TAG, msg);
18609                throw new SecurityException(msg);
18610            }
18611            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18612            if (stickies != null) {
18613                ArrayList<Intent> list = stickies.get(intent.getAction());
18614                if (list != null) {
18615                    int N = list.size();
18616                    int i;
18617                    for (i=0; i<N; i++) {
18618                        if (intent.filterEquals(list.get(i))) {
18619                            list.remove(i);
18620                            break;
18621                        }
18622                    }
18623                    if (list.size() <= 0) {
18624                        stickies.remove(intent.getAction());
18625                    }
18626                }
18627                if (stickies.size() <= 0) {
18628                    mStickyBroadcasts.remove(userId);
18629                }
18630            }
18631        }
18632    }
18633
18634    void backgroundServicesFinishedLocked(int userId) {
18635        for (BroadcastQueue queue : mBroadcastQueues) {
18636            queue.backgroundServicesFinishedLocked(userId);
18637        }
18638    }
18639
18640    public void finishReceiver(IBinder who, int resultCode, String resultData,
18641            Bundle resultExtras, boolean resultAbort, int flags) {
18642        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
18643
18644        // Refuse possible leaked file descriptors
18645        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
18646            throw new IllegalArgumentException("File descriptors passed in Bundle");
18647        }
18648
18649        final long origId = Binder.clearCallingIdentity();
18650        try {
18651            boolean doNext = false;
18652            BroadcastRecord r;
18653
18654            synchronized(this) {
18655                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
18656                        ? mFgBroadcastQueue : mBgBroadcastQueue;
18657                r = queue.getMatchingOrderedReceiver(who);
18658                if (r != null) {
18659                    doNext = r.queue.finishReceiverLocked(r, resultCode,
18660                        resultData, resultExtras, resultAbort, true);
18661                }
18662            }
18663
18664            if (doNext) {
18665                r.queue.processNextBroadcast(false);
18666            }
18667            trimApplications();
18668        } finally {
18669            Binder.restoreCallingIdentity(origId);
18670        }
18671    }
18672
18673    // =========================================================
18674    // INSTRUMENTATION
18675    // =========================================================
18676
18677    public boolean startInstrumentation(ComponentName className,
18678            String profileFile, int flags, Bundle arguments,
18679            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
18680            int userId, String abiOverride) {
18681        enforceNotIsolatedCaller("startInstrumentation");
18682        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18683                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
18684        // Refuse possible leaked file descriptors
18685        if (arguments != null && arguments.hasFileDescriptors()) {
18686            throw new IllegalArgumentException("File descriptors passed in Bundle");
18687        }
18688
18689        synchronized(this) {
18690            InstrumentationInfo ii = null;
18691            ApplicationInfo ai = null;
18692            try {
18693                ii = mContext.getPackageManager().getInstrumentationInfo(
18694                    className, STOCK_PM_FLAGS);
18695                ai = AppGlobals.getPackageManager().getApplicationInfo(
18696                        ii.targetPackage, STOCK_PM_FLAGS, userId);
18697            } catch (PackageManager.NameNotFoundException e) {
18698            } catch (RemoteException e) {
18699            }
18700            if (ii == null) {
18701                reportStartInstrumentationFailureLocked(watcher, className,
18702                        "Unable to find instrumentation info for: " + className);
18703                return false;
18704            }
18705            if (ai == null) {
18706                reportStartInstrumentationFailureLocked(watcher, className,
18707                        "Unable to find instrumentation target package: " + ii.targetPackage);
18708                return false;
18709            }
18710            if (!ai.hasCode()) {
18711                reportStartInstrumentationFailureLocked(watcher, className,
18712                        "Instrumentation target has no code: " + ii.targetPackage);
18713                return false;
18714            }
18715
18716            int match = mContext.getPackageManager().checkSignatures(
18717                    ii.targetPackage, ii.packageName);
18718            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18719                String msg = "Permission Denial: starting instrumentation "
18720                        + className + " from pid="
18721                        + Binder.getCallingPid()
18722                        + ", uid=" + Binder.getCallingPid()
18723                        + " not allowed because package " + ii.packageName
18724                        + " does not have a signature matching the target "
18725                        + ii.targetPackage;
18726                reportStartInstrumentationFailureLocked(watcher, className, msg);
18727                throw new SecurityException(msg);
18728            }
18729
18730            final long origId = Binder.clearCallingIdentity();
18731            // Instrumentation can kill and relaunch even persistent processes
18732            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18733                    "start instr");
18734            ProcessRecord app = addAppLocked(ai, false, abiOverride);
18735            app.instrumentationClass = className;
18736            app.instrumentationInfo = ai;
18737            app.instrumentationProfileFile = profileFile;
18738            app.instrumentationArguments = arguments;
18739            app.instrumentationWatcher = watcher;
18740            app.instrumentationUiAutomationConnection = uiAutomationConnection;
18741            app.instrumentationResultClass = className;
18742            Binder.restoreCallingIdentity(origId);
18743        }
18744
18745        return true;
18746    }
18747
18748    /**
18749     * Report errors that occur while attempting to start Instrumentation.  Always writes the
18750     * error to the logs, but if somebody is watching, send the report there too.  This enables
18751     * the "am" command to report errors with more information.
18752     *
18753     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
18754     * @param cn The component name of the instrumentation.
18755     * @param report The error report.
18756     */
18757    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18758            ComponentName cn, String report) {
18759        Slog.w(TAG, report);
18760        if (watcher != null) {
18761            Bundle results = new Bundle();
18762            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18763            results.putString("Error", report);
18764            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18765        }
18766    }
18767
18768    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18769        if (app.instrumentationWatcher != null) {
18770            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18771                    app.instrumentationClass, resultCode, results);
18772        }
18773
18774        // Can't call out of the system process with a lock held, so post a message.
18775        if (app.instrumentationUiAutomationConnection != null) {
18776            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18777                    app.instrumentationUiAutomationConnection).sendToTarget();
18778        }
18779
18780        app.instrumentationWatcher = null;
18781        app.instrumentationUiAutomationConnection = null;
18782        app.instrumentationClass = null;
18783        app.instrumentationInfo = null;
18784        app.instrumentationProfileFile = null;
18785        app.instrumentationArguments = null;
18786
18787        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18788                "finished inst");
18789    }
18790
18791    public void finishInstrumentation(IApplicationThread target,
18792            int resultCode, Bundle results) {
18793        int userId = UserHandle.getCallingUserId();
18794        // Refuse possible leaked file descriptors
18795        if (results != null && results.hasFileDescriptors()) {
18796            throw new IllegalArgumentException("File descriptors passed in Intent");
18797        }
18798
18799        synchronized(this) {
18800            ProcessRecord app = getRecordForAppLocked(target);
18801            if (app == null) {
18802                Slog.w(TAG, "finishInstrumentation: no app for " + target);
18803                return;
18804            }
18805            final long origId = Binder.clearCallingIdentity();
18806            finishInstrumentationLocked(app, resultCode, results);
18807            Binder.restoreCallingIdentity(origId);
18808        }
18809    }
18810
18811    // =========================================================
18812    // CONFIGURATION
18813    // =========================================================
18814
18815    public ConfigurationInfo getDeviceConfigurationInfo() {
18816        ConfigurationInfo config = new ConfigurationInfo();
18817        synchronized (this) {
18818            config.reqTouchScreen = mConfiguration.touchscreen;
18819            config.reqKeyboardType = mConfiguration.keyboard;
18820            config.reqNavigation = mConfiguration.navigation;
18821            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18822                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18823                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18824            }
18825            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18826                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18827                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18828            }
18829            config.reqGlEsVersion = GL_ES_VERSION;
18830        }
18831        return config;
18832    }
18833
18834    ActivityStack getFocusedStack() {
18835        return mStackSupervisor.getFocusedStack();
18836    }
18837
18838    @Override
18839    public int getFocusedStackId() throws RemoteException {
18840        ActivityStack focusedStack = getFocusedStack();
18841        if (focusedStack != null) {
18842            return focusedStack.getStackId();
18843        }
18844        return -1;
18845    }
18846
18847    public Configuration getConfiguration() {
18848        Configuration ci;
18849        synchronized(this) {
18850            ci = new Configuration(mConfiguration);
18851            ci.userSetLocale = false;
18852        }
18853        return ci;
18854    }
18855
18856    @Override
18857    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18858        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18859        synchronized (this) {
18860            mSuppressResizeConfigChanges = suppress;
18861        }
18862    }
18863
18864    @Override
18865    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18866        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18867        if (fromStackId == HOME_STACK_ID) {
18868            throw new IllegalArgumentException("You can't move tasks from the home stack.");
18869        }
18870        synchronized (this) {
18871            final long origId = Binder.clearCallingIdentity();
18872            try {
18873                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18874            } finally {
18875                Binder.restoreCallingIdentity(origId);
18876            }
18877        }
18878    }
18879
18880    @Override
18881    public void updatePersistentConfiguration(Configuration values) {
18882        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18883                "updateConfiguration()");
18884        enforceWriteSettingsPermission("updateConfiguration()");
18885        if (values == null) {
18886            throw new NullPointerException("Configuration must not be null");
18887        }
18888
18889        int userId = UserHandle.getCallingUserId();
18890
18891        synchronized(this) {
18892            updatePersistentConfigurationLocked(values, userId);
18893        }
18894    }
18895
18896    private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
18897        final long origId = Binder.clearCallingIdentity();
18898        try {
18899            updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
18900        } finally {
18901            Binder.restoreCallingIdentity(origId);
18902        }
18903    }
18904
18905    private void updateFontScaleIfNeeded(@UserIdInt int userId) {
18906        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18907                FONT_SCALE, 1.0f, userId);
18908        if (mConfiguration.fontScale != scaleFactor) {
18909            final Configuration configuration = mWindowManager.computeNewConfiguration();
18910            configuration.fontScale = scaleFactor;
18911            synchronized (this) {
18912                updatePersistentConfigurationLocked(configuration, userId);
18913            }
18914        }
18915    }
18916
18917    private void enforceWriteSettingsPermission(String func) {
18918        int uid = Binder.getCallingUid();
18919        if (uid == Process.ROOT_UID) {
18920            return;
18921        }
18922
18923        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18924                Settings.getPackageNameForUid(mContext, uid), false)) {
18925            return;
18926        }
18927
18928        String msg = "Permission Denial: " + func + " from pid="
18929                + Binder.getCallingPid()
18930                + ", uid=" + uid
18931                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18932        Slog.w(TAG, msg);
18933        throw new SecurityException(msg);
18934    }
18935
18936    public void updateConfiguration(Configuration values) {
18937        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18938                "updateConfiguration()");
18939
18940        synchronized(this) {
18941            if (values == null && mWindowManager != null) {
18942                // sentinel: fetch the current configuration from the window manager
18943                values = mWindowManager.computeNewConfiguration();
18944            }
18945
18946            if (mWindowManager != null) {
18947                mProcessList.applyDisplaySize(mWindowManager);
18948            }
18949
18950            final long origId = Binder.clearCallingIdentity();
18951            if (values != null) {
18952                Settings.System.clearConfiguration(values);
18953            }
18954            updateConfigurationLocked(values, null, false);
18955            Binder.restoreCallingIdentity(origId);
18956        }
18957    }
18958
18959    void updateUserConfigurationLocked() {
18960        Configuration configuration = new Configuration(mConfiguration);
18961        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
18962                mUserController.getCurrentUserIdLocked(), Settings.System.canWrite(mContext));
18963        updateConfigurationLocked(configuration, null, false);
18964    }
18965
18966    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
18967            boolean initLocale) {
18968        return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
18969    }
18970
18971    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
18972            boolean initLocale, boolean deferResume) {
18973        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18974        return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
18975                UserHandle.USER_NULL, deferResume);
18976    }
18977
18978    // To cache the list of supported system locales
18979    private String[] mSupportedSystemLocales = null;
18980
18981    /**
18982     * Do either or both things: (1) change the current configuration, and (2)
18983     * make sure the given activity is running with the (now) current
18984     * configuration.  Returns true if the activity has been left running, or
18985     * false if <var>starting</var> is being destroyed to match the new
18986     * configuration.
18987     *
18988     * @param userId is only used when persistent parameter is set to true to persist configuration
18989     *               for that particular user
18990     */
18991    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
18992            boolean initLocale, boolean persistent, int userId, boolean deferResume) {
18993        int changes = 0;
18994
18995        if (mWindowManager != null) {
18996            mWindowManager.deferSurfaceLayout();
18997        }
18998        if (values != null) {
18999            Configuration newConfig = new Configuration(mConfiguration);
19000            changes = newConfig.updateFrom(values);
19001            if (changes != 0) {
19002                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
19003                        "Updating configuration to: " + values);
19004
19005                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
19006
19007                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
19008                    final LocaleList locales = values.getLocales();
19009                    int bestLocaleIndex = 0;
19010                    if (locales.size() > 1) {
19011                        if (mSupportedSystemLocales == null) {
19012                            mSupportedSystemLocales =
19013                                    Resources.getSystem().getAssets().getLocales();
19014                        }
19015                        bestLocaleIndex = Math.max(0,
19016                                locales.getFirstMatchIndex(mSupportedSystemLocales));
19017                    }
19018                    SystemProperties.set("persist.sys.locale",
19019                            locales.get(bestLocaleIndex).toLanguageTag());
19020                    LocaleList.setDefault(locales, bestLocaleIndex);
19021                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
19022                            locales.get(bestLocaleIndex)));
19023                }
19024
19025                mConfigurationSeq++;
19026                if (mConfigurationSeq <= 0) {
19027                    mConfigurationSeq = 1;
19028                }
19029                newConfig.seq = mConfigurationSeq;
19030                mConfiguration = newConfig;
19031                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
19032                mUsageStatsService.reportConfigurationChange(newConfig,
19033                        mUserController.getCurrentUserIdLocked());
19034                //mUsageStatsService.noteStartConfig(newConfig);
19035
19036                final Configuration configCopy = new Configuration(mConfiguration);
19037
19038                // TODO: If our config changes, should we auto dismiss any currently
19039                // showing dialogs?
19040                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
19041
19042                AttributeCache ac = AttributeCache.instance();
19043                if (ac != null) {
19044                    ac.updateConfiguration(configCopy);
19045                }
19046
19047                // Make sure all resources in our process are updated
19048                // right now, so that anyone who is going to retrieve
19049                // resource values after we return will be sure to get
19050                // the new ones.  This is especially important during
19051                // boot, where the first config change needs to guarantee
19052                // all resources have that config before following boot
19053                // code is executed.
19054                mSystemThread.applyConfigurationToResources(configCopy);
19055
19056                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
19057                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
19058                    msg.obj = new Configuration(configCopy);
19059                    msg.arg1 = userId;
19060                    mHandler.sendMessage(msg);
19061                }
19062
19063                final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
19064                if (isDensityChange) {
19065                    // Reset the unsupported display size dialog.
19066                    mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
19067
19068                    killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
19069                            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
19070                }
19071
19072                for (int i=mLruProcesses.size()-1; i>=0; i--) {
19073                    ProcessRecord app = mLruProcesses.get(i);
19074                    try {
19075                        if (app.thread != null) {
19076                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
19077                                    + app.processName + " new config " + mConfiguration);
19078                            app.thread.scheduleConfigurationChanged(configCopy);
19079                        }
19080                    } catch (Exception e) {
19081                    }
19082                }
19083                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
19084                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19085                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
19086                        | Intent.FLAG_RECEIVER_FOREGROUND);
19087                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
19088                        null, AppOpsManager.OP_NONE, null, false, false,
19089                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19090                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
19091                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
19092                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
19093	            if (initLocale || !mProcessesReady) {
19094                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19095                    }
19096                    broadcastIntentLocked(null, null, intent,
19097                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19098                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19099                }
19100            }
19101            // Update the configuration with WM first and check if any of the stacks need to be
19102            // resized due to the configuration change. If so, resize the stacks now and do any
19103            // relaunches if necessary. This way we don't need to relaunch again below in
19104            // ensureActivityConfigurationLocked().
19105            if (mWindowManager != null) {
19106                final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
19107                if (resizedStacks != null) {
19108                    for (int stackId : resizedStacks) {
19109                        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
19110                        mStackSupervisor.resizeStackLocked(
19111                                stackId, newBounds, null, null, false, false, deferResume);
19112                    }
19113                }
19114            }
19115        }
19116
19117        boolean kept = true;
19118        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
19119        // mainStack is null during startup.
19120        if (mainStack != null) {
19121            if (changes != 0 && starting == null) {
19122                // If the configuration changed, and the caller is not already
19123                // in the process of starting an activity, then find the top
19124                // activity to check if its configuration needs to change.
19125                starting = mainStack.topRunningActivityLocked();
19126            }
19127
19128            if (starting != null) {
19129                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
19130                // And we need to make sure at this point that all other activities
19131                // are made visible with the correct configuration.
19132                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
19133                        !PRESERVE_WINDOWS);
19134            }
19135        }
19136        if (mWindowManager != null) {
19137            mWindowManager.continueSurfaceLayout();
19138        }
19139        return kept;
19140    }
19141
19142    /**
19143     * Decide based on the configuration whether we should shouw the ANR,
19144     * crash, etc dialogs.  The idea is that if there is no affordence to
19145     * press the on-screen buttons, or the user experience would be more
19146     * greatly impacted than the crash itself, we shouldn't show the dialog.
19147     *
19148     * A thought: SystemUI might also want to get told about this, the Power
19149     * dialog / global actions also might want different behaviors.
19150     */
19151    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
19152        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
19153                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
19154                                   && config.navigation == Configuration.NAVIGATION_NONAV);
19155        int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
19156        final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
19157                && !(modeType == Configuration.UI_MODE_TYPE_WATCH && "user".equals(Build.TYPE)));
19158        return inputMethodExists && uiModeSupportsDialogs && !inVrMode;
19159    }
19160
19161    @Override
19162    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
19163        synchronized (this) {
19164            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
19165            if (srec != null) {
19166                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
19167            }
19168        }
19169        return false;
19170    }
19171
19172    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
19173            Intent resultData) {
19174
19175        synchronized (this) {
19176            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
19177            if (r != null) {
19178                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
19179            }
19180            return false;
19181        }
19182    }
19183
19184    public int getLaunchedFromUid(IBinder activityToken) {
19185        ActivityRecord srec;
19186        synchronized (this) {
19187            srec = ActivityRecord.forTokenLocked(activityToken);
19188        }
19189        if (srec == null) {
19190            return -1;
19191        }
19192        return srec.launchedFromUid;
19193    }
19194
19195    public String getLaunchedFromPackage(IBinder activityToken) {
19196        ActivityRecord srec;
19197        synchronized (this) {
19198            srec = ActivityRecord.forTokenLocked(activityToken);
19199        }
19200        if (srec == null) {
19201            return null;
19202        }
19203        return srec.launchedFromPackage;
19204    }
19205
19206    // =========================================================
19207    // LIFETIME MANAGEMENT
19208    // =========================================================
19209
19210    // Returns whether the app is receiving broadcast.
19211    // If receiving, fetch all broadcast queues which the app is
19212    // the current [or imminent] receiver on.
19213    private boolean isReceivingBroadcastLocked(ProcessRecord app,
19214            ArraySet<BroadcastQueue> receivingQueues) {
19215        if (!app.curReceivers.isEmpty()) {
19216            for (BroadcastRecord r : app.curReceivers) {
19217                receivingQueues.add(r.queue);
19218            }
19219            return true;
19220        }
19221
19222        // It's not the current receiver, but it might be starting up to become one
19223        for (BroadcastQueue queue : mBroadcastQueues) {
19224            final BroadcastRecord r = queue.mPendingBroadcast;
19225            if (r != null && r.curApp == app) {
19226                // found it; report which queue it's in
19227                receivingQueues.add(queue);
19228            }
19229        }
19230
19231        return !receivingQueues.isEmpty();
19232    }
19233
19234    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
19235            int targetUid, ComponentName targetComponent, String targetProcess) {
19236        if (!mTrackingAssociations) {
19237            return null;
19238        }
19239        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19240                = mAssociations.get(targetUid);
19241        if (components == null) {
19242            components = new ArrayMap<>();
19243            mAssociations.put(targetUid, components);
19244        }
19245        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19246        if (sourceUids == null) {
19247            sourceUids = new SparseArray<>();
19248            components.put(targetComponent, sourceUids);
19249        }
19250        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19251        if (sourceProcesses == null) {
19252            sourceProcesses = new ArrayMap<>();
19253            sourceUids.put(sourceUid, sourceProcesses);
19254        }
19255        Association ass = sourceProcesses.get(sourceProcess);
19256        if (ass == null) {
19257            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
19258                    targetProcess);
19259            sourceProcesses.put(sourceProcess, ass);
19260        }
19261        ass.mCount++;
19262        ass.mNesting++;
19263        if (ass.mNesting == 1) {
19264            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
19265            ass.mLastState = sourceState;
19266        }
19267        return ass;
19268    }
19269
19270    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
19271            ComponentName targetComponent) {
19272        if (!mTrackingAssociations) {
19273            return;
19274        }
19275        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19276                = mAssociations.get(targetUid);
19277        if (components == null) {
19278            return;
19279        }
19280        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19281        if (sourceUids == null) {
19282            return;
19283        }
19284        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19285        if (sourceProcesses == null) {
19286            return;
19287        }
19288        Association ass = sourceProcesses.get(sourceProcess);
19289        if (ass == null || ass.mNesting <= 0) {
19290            return;
19291        }
19292        ass.mNesting--;
19293        if (ass.mNesting == 0) {
19294            long uptime = SystemClock.uptimeMillis();
19295            ass.mTime += uptime - ass.mStartTime;
19296            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19297                    += uptime - ass.mLastStateUptime;
19298            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
19299        }
19300    }
19301
19302    private void noteUidProcessState(final int uid, final int state) {
19303        mBatteryStatsService.noteUidProcessState(uid, state);
19304        if (mTrackingAssociations) {
19305            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
19306                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
19307                        = mAssociations.valueAt(i1);
19308                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
19309                    SparseArray<ArrayMap<String, Association>> sourceUids
19310                            = targetComponents.valueAt(i2);
19311                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
19312                    if (sourceProcesses != null) {
19313                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
19314                            Association ass = sourceProcesses.valueAt(i4);
19315                            if (ass.mNesting >= 1) {
19316                                // currently associated
19317                                long uptime = SystemClock.uptimeMillis();
19318                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19319                                        += uptime - ass.mLastStateUptime;
19320                                ass.mLastState = state;
19321                                ass.mLastStateUptime = uptime;
19322                            }
19323                        }
19324                    }
19325                }
19326            }
19327        }
19328    }
19329
19330    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
19331            boolean doingAll, long now) {
19332        if (mAdjSeq == app.adjSeq) {
19333            // This adjustment has already been computed.
19334            return app.curRawAdj;
19335        }
19336
19337        if (app.thread == null) {
19338            app.adjSeq = mAdjSeq;
19339            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19340            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19341            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
19342        }
19343
19344        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
19345        app.adjSource = null;
19346        app.adjTarget = null;
19347        app.empty = false;
19348        app.cached = false;
19349
19350        final int activitiesSize = app.activities.size();
19351
19352        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19353            // The max adjustment doesn't allow this app to be anything
19354            // below foreground, so it is not worth doing work for it.
19355            app.adjType = "fixed";
19356            app.adjSeq = mAdjSeq;
19357            app.curRawAdj = app.maxAdj;
19358            app.foregroundActivities = false;
19359            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19360            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
19361            // System processes can do UI, and when they do we want to have
19362            // them trim their memory after the user leaves the UI.  To
19363            // facilitate this, here we need to determine whether or not it
19364            // is currently showing UI.
19365            app.systemNoUi = true;
19366            if (app == TOP_APP) {
19367                app.systemNoUi = false;
19368                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19369                app.adjType = "pers-top-activity";
19370            } else if (app.hasTopUi) {
19371                app.systemNoUi = false;
19372                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19373                app.adjType = "pers-top-ui";
19374            } else if (activitiesSize > 0) {
19375                for (int j = 0; j < activitiesSize; j++) {
19376                    final ActivityRecord r = app.activities.get(j);
19377                    if (r.visible) {
19378                        app.systemNoUi = false;
19379                    }
19380                }
19381            }
19382            if (!app.systemNoUi) {
19383                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
19384            }
19385            return (app.curAdj=app.maxAdj);
19386        }
19387
19388        app.systemNoUi = false;
19389
19390        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
19391
19392        // Determine the importance of the process, starting with most
19393        // important to least, and assign an appropriate OOM adjustment.
19394        int adj;
19395        int schedGroup;
19396        int procState;
19397        boolean foregroundActivities = false;
19398        final ArraySet<BroadcastQueue> queues = new ArraySet<BroadcastQueue>();
19399        if (app == TOP_APP) {
19400            // The last app on the list is the foreground app.
19401            adj = ProcessList.FOREGROUND_APP_ADJ;
19402            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19403            app.adjType = "top-activity";
19404            foregroundActivities = true;
19405            procState = PROCESS_STATE_CUR_TOP;
19406        } else if (app.instrumentationClass != null) {
19407            // Don't want to kill running instrumentation.
19408            adj = ProcessList.FOREGROUND_APP_ADJ;
19409            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19410            app.adjType = "instrumentation";
19411            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19412        } else if (isReceivingBroadcastLocked(app, queues)) {
19413            // An app that is currently receiving a broadcast also
19414            // counts as being in the foreground for OOM killer purposes.
19415            // It's placed in a sched group based on the nature of the
19416            // broadcast as reflected by which queue it's active in.
19417            adj = ProcessList.FOREGROUND_APP_ADJ;
19418            schedGroup = (queues.contains(mFgBroadcastQueue))
19419                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19420            app.adjType = "broadcast";
19421            procState = ActivityManager.PROCESS_STATE_RECEIVER;
19422        } else if (app.executingServices.size() > 0) {
19423            // An app that is currently executing a service callback also
19424            // counts as being in the foreground.
19425            adj = ProcessList.FOREGROUND_APP_ADJ;
19426            schedGroup = app.execServicesFg ?
19427                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19428            app.adjType = "exec-service";
19429            procState = ActivityManager.PROCESS_STATE_SERVICE;
19430            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
19431        } else {
19432            // As far as we know the process is empty.  We may change our mind later.
19433            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19434            // At this point we don't actually know the adjustment.  Use the cached adj
19435            // value that the caller wants us to.
19436            adj = cachedAdj;
19437            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19438            app.cached = true;
19439            app.empty = true;
19440            app.adjType = "cch-empty";
19441        }
19442
19443        // Examine all activities if not already foreground.
19444        if (!foregroundActivities && activitiesSize > 0) {
19445            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
19446            for (int j = 0; j < activitiesSize; j++) {
19447                final ActivityRecord r = app.activities.get(j);
19448                if (r.app != app) {
19449                    Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
19450                            + " instead of expected " + app);
19451                    if (r.app == null || (r.app.uid == app.uid)) {
19452                        // Only fix things up when they look sane
19453                        r.app = app;
19454                    } else {
19455                        continue;
19456                    }
19457                }
19458                if (r.visible) {
19459                    // App has a visible activity; only upgrade adjustment.
19460                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19461                        adj = ProcessList.VISIBLE_APP_ADJ;
19462                        app.adjType = "visible";
19463                    }
19464                    if (procState > PROCESS_STATE_CUR_TOP) {
19465                        procState = PROCESS_STATE_CUR_TOP;
19466                    }
19467                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19468                    app.cached = false;
19469                    app.empty = false;
19470                    foregroundActivities = true;
19471                    if (r.task != null && minLayer > 0) {
19472                        final int layer = r.task.mLayerRank;
19473                        if (layer >= 0 && minLayer > layer) {
19474                            minLayer = layer;
19475                        }
19476                    }
19477                    break;
19478                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
19479                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19480                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19481                        app.adjType = "pausing";
19482                    }
19483                    if (procState > PROCESS_STATE_CUR_TOP) {
19484                        procState = PROCESS_STATE_CUR_TOP;
19485                    }
19486                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19487                    app.cached = false;
19488                    app.empty = false;
19489                    foregroundActivities = true;
19490                } else if (r.state == ActivityState.STOPPING) {
19491                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19492                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19493                        app.adjType = "stopping";
19494                    }
19495                    // For the process state, we will at this point consider the
19496                    // process to be cached.  It will be cached either as an activity
19497                    // or empty depending on whether the activity is finishing.  We do
19498                    // this so that we can treat the process as cached for purposes of
19499                    // memory trimming (determing current memory level, trim command to
19500                    // send to process) since there can be an arbitrary number of stopping
19501                    // processes and they should soon all go into the cached state.
19502                    if (!r.finishing) {
19503                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19504                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19505                        }
19506                    }
19507                    app.cached = false;
19508                    app.empty = false;
19509                    foregroundActivities = true;
19510                } else {
19511                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19512                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19513                        app.adjType = "cch-act";
19514                    }
19515                }
19516            }
19517            if (adj == ProcessList.VISIBLE_APP_ADJ) {
19518                adj += minLayer;
19519            }
19520        }
19521
19522        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
19523                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
19524            if (app.foregroundServices) {
19525                // The user is aware of this app, so make it visible.
19526                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19527                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19528                app.cached = false;
19529                app.adjType = "fg-service";
19530                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19531            } else if (app.forcingToForeground != null) {
19532                // The user is aware of this app, so make it visible.
19533                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19534                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19535                app.cached = false;
19536                app.adjType = "force-fg";
19537                app.adjSource = app.forcingToForeground;
19538                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19539            }
19540        }
19541
19542        if (app == mHeavyWeightProcess) {
19543            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
19544                // We don't want to kill the current heavy-weight process.
19545                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
19546                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19547                app.cached = false;
19548                app.adjType = "heavy";
19549            }
19550            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19551                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
19552            }
19553        }
19554
19555        if (app == mHomeProcess) {
19556            if (adj > ProcessList.HOME_APP_ADJ) {
19557                // This process is hosting what we currently consider to be the
19558                // home app, so we don't want to let it go into the background.
19559                adj = ProcessList.HOME_APP_ADJ;
19560                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19561                app.cached = false;
19562                app.adjType = "home";
19563            }
19564            if (procState > ActivityManager.PROCESS_STATE_HOME) {
19565                procState = ActivityManager.PROCESS_STATE_HOME;
19566            }
19567        }
19568
19569        if (app == mPreviousProcess && app.activities.size() > 0) {
19570            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19571                // This was the previous process that showed UI to the user.
19572                // We want to try to keep it around more aggressively, to give
19573                // a good experience around switching between two apps.
19574                adj = ProcessList.PREVIOUS_APP_ADJ;
19575                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19576                app.cached = false;
19577                app.adjType = "previous";
19578            }
19579            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19580                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19581            }
19582        }
19583
19584        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
19585                + " reason=" + app.adjType);
19586
19587        // By default, we use the computed adjustment.  It may be changed if
19588        // there are applications dependent on our services or providers, but
19589        // this gives us a baseline and makes sure we don't get into an
19590        // infinite recursion.
19591        app.adjSeq = mAdjSeq;
19592        app.curRawAdj = adj;
19593        app.hasStartedServices = false;
19594
19595        if (mBackupTarget != null && app == mBackupTarget.app) {
19596            // If possible we want to avoid killing apps while they're being backed up
19597            if (adj > ProcessList.BACKUP_APP_ADJ) {
19598                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
19599                adj = ProcessList.BACKUP_APP_ADJ;
19600                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19601                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19602                }
19603                app.adjType = "backup";
19604                app.cached = false;
19605            }
19606            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
19607                procState = ActivityManager.PROCESS_STATE_BACKUP;
19608            }
19609        }
19610
19611        boolean mayBeTop = false;
19612
19613        for (int is = app.services.size()-1;
19614                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19615                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19616                        || procState > ActivityManager.PROCESS_STATE_TOP);
19617                is--) {
19618            ServiceRecord s = app.services.valueAt(is);
19619            if (s.startRequested) {
19620                app.hasStartedServices = true;
19621                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
19622                    procState = ActivityManager.PROCESS_STATE_SERVICE;
19623                }
19624                if (app.hasShownUi && app != mHomeProcess) {
19625                    // If this process has shown some UI, let it immediately
19626                    // go to the LRU list because it may be pretty heavy with
19627                    // UI stuff.  We'll tag it with a label just to help
19628                    // debug and understand what is going on.
19629                    if (adj > ProcessList.SERVICE_ADJ) {
19630                        app.adjType = "cch-started-ui-services";
19631                    }
19632                } else {
19633                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19634                        // This service has seen some activity within
19635                        // recent memory, so we will keep its process ahead
19636                        // of the background processes.
19637                        if (adj > ProcessList.SERVICE_ADJ) {
19638                            adj = ProcessList.SERVICE_ADJ;
19639                            app.adjType = "started-services";
19640                            app.cached = false;
19641                        }
19642                    }
19643                    // If we have let the service slide into the background
19644                    // state, still have some text describing what it is doing
19645                    // even though the service no longer has an impact.
19646                    if (adj > ProcessList.SERVICE_ADJ) {
19647                        app.adjType = "cch-started-services";
19648                    }
19649                }
19650            }
19651
19652            for (int conni = s.connections.size()-1;
19653                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19654                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19655                            || procState > ActivityManager.PROCESS_STATE_TOP);
19656                    conni--) {
19657                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
19658                for (int i = 0;
19659                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
19660                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19661                                || procState > ActivityManager.PROCESS_STATE_TOP);
19662                        i++) {
19663                    // XXX should compute this based on the max of
19664                    // all connected clients.
19665                    ConnectionRecord cr = clist.get(i);
19666                    if (cr.binding.client == app) {
19667                        // Binding to ourself is not interesting.
19668                        continue;
19669                    }
19670
19671                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
19672                        ProcessRecord client = cr.binding.client;
19673                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
19674                                TOP_APP, doingAll, now);
19675                        int clientProcState = client.curProcState;
19676                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19677                            // If the other app is cached for any reason, for purposes here
19678                            // we are going to consider it empty.  The specific cached state
19679                            // doesn't propagate except under certain conditions.
19680                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19681                        }
19682                        String adjType = null;
19683                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
19684                            // Not doing bind OOM management, so treat
19685                            // this guy more like a started service.
19686                            if (app.hasShownUi && app != mHomeProcess) {
19687                                // If this process has shown some UI, let it immediately
19688                                // go to the LRU list because it may be pretty heavy with
19689                                // UI stuff.  We'll tag it with a label just to help
19690                                // debug and understand what is going on.
19691                                if (adj > clientAdj) {
19692                                    adjType = "cch-bound-ui-services";
19693                                }
19694                                app.cached = false;
19695                                clientAdj = adj;
19696                                clientProcState = procState;
19697                            } else {
19698                                if (now >= (s.lastActivity
19699                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19700                                    // This service has not seen activity within
19701                                    // recent memory, so allow it to drop to the
19702                                    // LRU list if there is no other reason to keep
19703                                    // it around.  We'll also tag it with a label just
19704                                    // to help debug and undertand what is going on.
19705                                    if (adj > clientAdj) {
19706                                        adjType = "cch-bound-services";
19707                                    }
19708                                    clientAdj = adj;
19709                                }
19710                            }
19711                        }
19712                        if (adj > clientAdj) {
19713                            // If this process has recently shown UI, and
19714                            // the process that is binding to it is less
19715                            // important than being visible, then we don't
19716                            // care about the binding as much as we care
19717                            // about letting this process get into the LRU
19718                            // list to be killed and restarted if needed for
19719                            // memory.
19720                            if (app.hasShownUi && app != mHomeProcess
19721                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19722                                adjType = "cch-bound-ui-services";
19723                            } else {
19724                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
19725                                        |Context.BIND_IMPORTANT)) != 0) {
19726                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
19727                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
19728                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
19729                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
19730                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19731                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19732                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
19733                                    adj = clientAdj;
19734                                } else {
19735                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19736                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
19737                                    }
19738                                }
19739                                if (!client.cached) {
19740                                    app.cached = false;
19741                                }
19742                                adjType = "service";
19743                            }
19744                        }
19745                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19746                            // This will treat important bound services identically to
19747                            // the top app, which may behave differently than generic
19748                            // foreground work.
19749                            if (client.curSchedGroup > schedGroup) {
19750                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19751                                    schedGroup = client.curSchedGroup;
19752                                } else {
19753                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19754                                }
19755                            }
19756                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19757                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19758                                    // Special handling of clients who are in the top state.
19759                                    // We *may* want to consider this process to be in the
19760                                    // top state as well, but only if there is not another
19761                                    // reason for it to be running.  Being on the top is a
19762                                    // special state, meaning you are specifically running
19763                                    // for the current top app.  If the process is already
19764                                    // running in the background for some other reason, it
19765                                    // is more important to continue considering it to be
19766                                    // in the background state.
19767                                    mayBeTop = true;
19768                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19769                                } else {
19770                                    // Special handling for above-top states (persistent
19771                                    // processes).  These should not bring the current process
19772                                    // into the top state, since they are not on top.  Instead
19773                                    // give them the best state after that.
19774                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
19775                                        clientProcState =
19776                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19777                                    } else if (mWakefulness
19778                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
19779                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
19780                                                    != 0) {
19781                                        clientProcState =
19782                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19783                                    } else {
19784                                        clientProcState =
19785                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19786                                    }
19787                                }
19788                            }
19789                        } else {
19790                            if (clientProcState <
19791                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19792                                clientProcState =
19793                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19794                            }
19795                        }
19796                        if (procState > clientProcState) {
19797                            procState = clientProcState;
19798                        }
19799                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19800                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
19801                            app.pendingUiClean = true;
19802                        }
19803                        if (adjType != null) {
19804                            app.adjType = adjType;
19805                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19806                                    .REASON_SERVICE_IN_USE;
19807                            app.adjSource = cr.binding.client;
19808                            app.adjSourceProcState = clientProcState;
19809                            app.adjTarget = s.name;
19810                        }
19811                    }
19812                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
19813                        app.treatLikeActivity = true;
19814                    }
19815                    final ActivityRecord a = cr.activity;
19816                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
19817                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19818                            (a.visible || a.state == ActivityState.RESUMED ||
19819                             a.state == ActivityState.PAUSING)) {
19820                            adj = ProcessList.FOREGROUND_APP_ADJ;
19821                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19822                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19823                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
19824                                } else {
19825                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19826                                }
19827                            }
19828                            app.cached = false;
19829                            app.adjType = "service";
19830                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19831                                    .REASON_SERVICE_IN_USE;
19832                            app.adjSource = a;
19833                            app.adjSourceProcState = procState;
19834                            app.adjTarget = s.name;
19835                        }
19836                    }
19837                }
19838            }
19839        }
19840
19841        for (int provi = app.pubProviders.size()-1;
19842                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19843                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19844                        || procState > ActivityManager.PROCESS_STATE_TOP);
19845                provi--) {
19846            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19847            for (int i = cpr.connections.size()-1;
19848                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19849                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19850                            || procState > ActivityManager.PROCESS_STATE_TOP);
19851                    i--) {
19852                ContentProviderConnection conn = cpr.connections.get(i);
19853                ProcessRecord client = conn.client;
19854                if (client == app) {
19855                    // Being our own client is not interesting.
19856                    continue;
19857                }
19858                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19859                int clientProcState = client.curProcState;
19860                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19861                    // If the other app is cached for any reason, for purposes here
19862                    // we are going to consider it empty.
19863                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19864                }
19865                if (adj > clientAdj) {
19866                    if (app.hasShownUi && app != mHomeProcess
19867                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19868                        app.adjType = "cch-ui-provider";
19869                    } else {
19870                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19871                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19872                        app.adjType = "provider";
19873                    }
19874                    app.cached &= client.cached;
19875                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19876                            .REASON_PROVIDER_IN_USE;
19877                    app.adjSource = client;
19878                    app.adjSourceProcState = clientProcState;
19879                    app.adjTarget = cpr.name;
19880                }
19881                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19882                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19883                        // Special handling of clients who are in the top state.
19884                        // We *may* want to consider this process to be in the
19885                        // top state as well, but only if there is not another
19886                        // reason for it to be running.  Being on the top is a
19887                        // special state, meaning you are specifically running
19888                        // for the current top app.  If the process is already
19889                        // running in the background for some other reason, it
19890                        // is more important to continue considering it to be
19891                        // in the background state.
19892                        mayBeTop = true;
19893                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19894                    } else {
19895                        // Special handling for above-top states (persistent
19896                        // processes).  These should not bring the current process
19897                        // into the top state, since they are not on top.  Instead
19898                        // give them the best state after that.
19899                        clientProcState =
19900                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19901                    }
19902                }
19903                if (procState > clientProcState) {
19904                    procState = clientProcState;
19905                }
19906                if (client.curSchedGroup > schedGroup) {
19907                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19908                }
19909            }
19910            // If the provider has external (non-framework) process
19911            // dependencies, ensure that its adjustment is at least
19912            // FOREGROUND_APP_ADJ.
19913            if (cpr.hasExternalProcessHandles()) {
19914                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19915                    adj = ProcessList.FOREGROUND_APP_ADJ;
19916                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19917                    app.cached = false;
19918                    app.adjType = "provider";
19919                    app.adjTarget = cpr.name;
19920                }
19921                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19922                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19923                }
19924            }
19925        }
19926
19927        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19928            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19929                adj = ProcessList.PREVIOUS_APP_ADJ;
19930                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19931                app.cached = false;
19932                app.adjType = "provider";
19933            }
19934            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19935                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19936            }
19937        }
19938
19939        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19940            // A client of one of our services or providers is in the top state.  We
19941            // *may* want to be in the top state, but not if we are already running in
19942            // the background for some other reason.  For the decision here, we are going
19943            // to pick out a few specific states that we want to remain in when a client
19944            // is top (states that tend to be longer-term) and otherwise allow it to go
19945            // to the top state.
19946            switch (procState) {
19947                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19948                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19949                case ActivityManager.PROCESS_STATE_SERVICE:
19950                    // These all are longer-term states, so pull them up to the top
19951                    // of the background states, but not all the way to the top state.
19952                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19953                    break;
19954                default:
19955                    // Otherwise, top is a better choice, so take it.
19956                    procState = ActivityManager.PROCESS_STATE_TOP;
19957                    break;
19958            }
19959        }
19960
19961        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19962            if (app.hasClientActivities) {
19963                // This is a cached process, but with client activities.  Mark it so.
19964                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19965                app.adjType = "cch-client-act";
19966            } else if (app.treatLikeActivity) {
19967                // This is a cached process, but somebody wants us to treat it like it has
19968                // an activity, okay!
19969                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19970                app.adjType = "cch-as-act";
19971            }
19972        }
19973
19974        if (adj == ProcessList.SERVICE_ADJ) {
19975            if (doingAll) {
19976                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19977                mNewNumServiceProcs++;
19978                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19979                if (!app.serviceb) {
19980                    // This service isn't far enough down on the LRU list to
19981                    // normally be a B service, but if we are low on RAM and it
19982                    // is large we want to force it down since we would prefer to
19983                    // keep launcher over it.
19984                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19985                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19986                        app.serviceHighRam = true;
19987                        app.serviceb = true;
19988                        //Slog.i(TAG, "ADJ " + app + " high ram!");
19989                    } else {
19990                        mNewNumAServiceProcs++;
19991                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
19992                    }
19993                } else {
19994                    app.serviceHighRam = false;
19995                }
19996            }
19997            if (app.serviceb) {
19998                adj = ProcessList.SERVICE_B_ADJ;
19999            }
20000        }
20001
20002        app.curRawAdj = adj;
20003
20004        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
20005        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
20006        if (adj > app.maxAdj) {
20007            adj = app.maxAdj;
20008            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
20009                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20010            }
20011        }
20012
20013        // Do final modification to adj.  Everything we do between here and applying
20014        // the final setAdj must be done in this function, because we will also use
20015        // it when computing the final cached adj later.  Note that we don't need to
20016        // worry about this for max adj above, since max adj will always be used to
20017        // keep it out of the cached vaues.
20018        app.curAdj = app.modifyRawOomAdj(adj);
20019        app.curSchedGroup = schedGroup;
20020        app.curProcState = procState;
20021        app.foregroundActivities = foregroundActivities;
20022
20023        return app.curRawAdj;
20024    }
20025
20026    /**
20027     * Record new PSS sample for a process.
20028     */
20029    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
20030            long now) {
20031        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
20032                swapPss * 1024);
20033        proc.lastPssTime = now;
20034        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
20035        if (DEBUG_PSS) Slog.d(TAG_PSS,
20036                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
20037                + " state=" + ProcessList.makeProcStateString(procState));
20038        if (proc.initialIdlePss == 0) {
20039            proc.initialIdlePss = pss;
20040        }
20041        proc.lastPss = pss;
20042        proc.lastSwapPss = swapPss;
20043        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
20044            proc.lastCachedPss = pss;
20045            proc.lastCachedSwapPss = swapPss;
20046        }
20047
20048        final SparseArray<Pair<Long, String>> watchUids
20049                = mMemWatchProcesses.getMap().get(proc.processName);
20050        Long check = null;
20051        if (watchUids != null) {
20052            Pair<Long, String> val = watchUids.get(proc.uid);
20053            if (val == null) {
20054                val = watchUids.get(0);
20055            }
20056            if (val != null) {
20057                check = val.first;
20058            }
20059        }
20060        if (check != null) {
20061            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
20062                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20063                if (!isDebuggable) {
20064                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
20065                        isDebuggable = true;
20066                    }
20067                }
20068                if (isDebuggable) {
20069                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
20070                    final ProcessRecord myProc = proc;
20071                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
20072                    mMemWatchDumpProcName = proc.processName;
20073                    mMemWatchDumpFile = heapdumpFile.toString();
20074                    mMemWatchDumpPid = proc.pid;
20075                    mMemWatchDumpUid = proc.uid;
20076                    BackgroundThread.getHandler().post(new Runnable() {
20077                        @Override
20078                        public void run() {
20079                            revokeUriPermission(ActivityThread.currentActivityThread()
20080                                            .getApplicationThread(),
20081                                    DumpHeapActivity.JAVA_URI,
20082                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
20083                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
20084                                    UserHandle.myUserId());
20085                            ParcelFileDescriptor fd = null;
20086                            try {
20087                                heapdumpFile.delete();
20088                                fd = ParcelFileDescriptor.open(heapdumpFile,
20089                                        ParcelFileDescriptor.MODE_CREATE |
20090                                                ParcelFileDescriptor.MODE_TRUNCATE |
20091                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
20092                                                ParcelFileDescriptor.MODE_APPEND);
20093                                IApplicationThread thread = myProc.thread;
20094                                if (thread != null) {
20095                                    try {
20096                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
20097                                                "Requesting dump heap from "
20098                                                + myProc + " to " + heapdumpFile);
20099                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
20100                                    } catch (RemoteException e) {
20101                                    }
20102                                }
20103                            } catch (FileNotFoundException e) {
20104                                e.printStackTrace();
20105                            } finally {
20106                                if (fd != null) {
20107                                    try {
20108                                        fd.close();
20109                                    } catch (IOException e) {
20110                                    }
20111                                }
20112                            }
20113                        }
20114                    });
20115                } else {
20116                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
20117                            + ", but debugging not enabled");
20118                }
20119            }
20120        }
20121    }
20122
20123    /**
20124     * Schedule PSS collection of a process.
20125     */
20126    void requestPssLocked(ProcessRecord proc, int procState) {
20127        if (mPendingPssProcesses.contains(proc)) {
20128            return;
20129        }
20130        if (mPendingPssProcesses.size() == 0) {
20131            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
20132        }
20133        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
20134        proc.pssProcState = procState;
20135        mPendingPssProcesses.add(proc);
20136    }
20137
20138    /**
20139     * Schedule PSS collection of all processes.
20140     */
20141    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
20142        if (!always) {
20143            if (now < (mLastFullPssTime +
20144                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
20145                return;
20146            }
20147        }
20148        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
20149        mLastFullPssTime = now;
20150        mFullPssPending = true;
20151        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
20152        mPendingPssProcesses.clear();
20153        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20154            ProcessRecord app = mLruProcesses.get(i);
20155            if (app.thread == null
20156                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
20157                continue;
20158            }
20159            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
20160                app.pssProcState = app.setProcState;
20161                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20162                        mTestPssMode, isSleepingLocked(), now);
20163                mPendingPssProcesses.add(app);
20164            }
20165        }
20166        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
20167    }
20168
20169    public void setTestPssMode(boolean enabled) {
20170        synchronized (this) {
20171            mTestPssMode = enabled;
20172            if (enabled) {
20173                // Whenever we enable the mode, we want to take a snapshot all of current
20174                // process mem use.
20175                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
20176            }
20177        }
20178    }
20179
20180    /**
20181     * Ask a given process to GC right now.
20182     */
20183    final void performAppGcLocked(ProcessRecord app) {
20184        try {
20185            app.lastRequestedGc = SystemClock.uptimeMillis();
20186            if (app.thread != null) {
20187                if (app.reportLowMemory) {
20188                    app.reportLowMemory = false;
20189                    app.thread.scheduleLowMemory();
20190                } else {
20191                    app.thread.processInBackground();
20192                }
20193            }
20194        } catch (Exception e) {
20195            // whatever.
20196        }
20197    }
20198
20199    /**
20200     * Returns true if things are idle enough to perform GCs.
20201     */
20202    private final boolean canGcNowLocked() {
20203        boolean processingBroadcasts = false;
20204        for (BroadcastQueue q : mBroadcastQueues) {
20205            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
20206                processingBroadcasts = true;
20207            }
20208        }
20209        return !processingBroadcasts
20210                && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
20211    }
20212
20213    /**
20214     * Perform GCs on all processes that are waiting for it, but only
20215     * if things are idle.
20216     */
20217    final void performAppGcsLocked() {
20218        final int N = mProcessesToGc.size();
20219        if (N <= 0) {
20220            return;
20221        }
20222        if (canGcNowLocked()) {
20223            while (mProcessesToGc.size() > 0) {
20224                ProcessRecord proc = mProcessesToGc.remove(0);
20225                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
20226                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
20227                            <= SystemClock.uptimeMillis()) {
20228                        // To avoid spamming the system, we will GC processes one
20229                        // at a time, waiting a few seconds between each.
20230                        performAppGcLocked(proc);
20231                        scheduleAppGcsLocked();
20232                        return;
20233                    } else {
20234                        // It hasn't been long enough since we last GCed this
20235                        // process...  put it in the list to wait for its time.
20236                        addProcessToGcListLocked(proc);
20237                        break;
20238                    }
20239                }
20240            }
20241
20242            scheduleAppGcsLocked();
20243        }
20244    }
20245
20246    /**
20247     * If all looks good, perform GCs on all processes waiting for them.
20248     */
20249    final void performAppGcsIfAppropriateLocked() {
20250        if (canGcNowLocked()) {
20251            performAppGcsLocked();
20252            return;
20253        }
20254        // Still not idle, wait some more.
20255        scheduleAppGcsLocked();
20256    }
20257
20258    /**
20259     * Schedule the execution of all pending app GCs.
20260     */
20261    final void scheduleAppGcsLocked() {
20262        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
20263
20264        if (mProcessesToGc.size() > 0) {
20265            // Schedule a GC for the time to the next process.
20266            ProcessRecord proc = mProcessesToGc.get(0);
20267            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
20268
20269            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
20270            long now = SystemClock.uptimeMillis();
20271            if (when < (now+GC_TIMEOUT)) {
20272                when = now + GC_TIMEOUT;
20273            }
20274            mHandler.sendMessageAtTime(msg, when);
20275        }
20276    }
20277
20278    /**
20279     * Add a process to the array of processes waiting to be GCed.  Keeps the
20280     * list in sorted order by the last GC time.  The process can't already be
20281     * on the list.
20282     */
20283    final void addProcessToGcListLocked(ProcessRecord proc) {
20284        boolean added = false;
20285        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
20286            if (mProcessesToGc.get(i).lastRequestedGc <
20287                    proc.lastRequestedGc) {
20288                added = true;
20289                mProcessesToGc.add(i+1, proc);
20290                break;
20291            }
20292        }
20293        if (!added) {
20294            mProcessesToGc.add(0, proc);
20295        }
20296    }
20297
20298    /**
20299     * Set up to ask a process to GC itself.  This will either do it
20300     * immediately, or put it on the list of processes to gc the next
20301     * time things are idle.
20302     */
20303    final void scheduleAppGcLocked(ProcessRecord app) {
20304        long now = SystemClock.uptimeMillis();
20305        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
20306            return;
20307        }
20308        if (!mProcessesToGc.contains(app)) {
20309            addProcessToGcListLocked(app);
20310            scheduleAppGcsLocked();
20311        }
20312    }
20313
20314    final void checkExcessivePowerUsageLocked(boolean doKills) {
20315        updateCpuStatsNow();
20316
20317        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20318        boolean doWakeKills = doKills;
20319        boolean doCpuKills = doKills;
20320        if (mLastPowerCheckRealtime == 0) {
20321            doWakeKills = false;
20322        }
20323        if (mLastPowerCheckUptime == 0) {
20324            doCpuKills = false;
20325        }
20326        if (stats.isScreenOn()) {
20327            doWakeKills = false;
20328        }
20329        final long curRealtime = SystemClock.elapsedRealtime();
20330        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
20331        final long curUptime = SystemClock.uptimeMillis();
20332        final long uptimeSince = curUptime - mLastPowerCheckUptime;
20333        mLastPowerCheckRealtime = curRealtime;
20334        mLastPowerCheckUptime = curUptime;
20335        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
20336            doWakeKills = false;
20337        }
20338        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
20339            doCpuKills = false;
20340        }
20341        int i = mLruProcesses.size();
20342        while (i > 0) {
20343            i--;
20344            ProcessRecord app = mLruProcesses.get(i);
20345            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20346                long wtime;
20347                synchronized (stats) {
20348                    wtime = stats.getProcessWakeTime(app.info.uid,
20349                            app.pid, curRealtime);
20350                }
20351                long wtimeUsed = wtime - app.lastWakeTime;
20352                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
20353                if (DEBUG_POWER) {
20354                    StringBuilder sb = new StringBuilder(128);
20355                    sb.append("Wake for ");
20356                    app.toShortString(sb);
20357                    sb.append(": over ");
20358                    TimeUtils.formatDuration(realtimeSince, sb);
20359                    sb.append(" used ");
20360                    TimeUtils.formatDuration(wtimeUsed, sb);
20361                    sb.append(" (");
20362                    sb.append((wtimeUsed*100)/realtimeSince);
20363                    sb.append("%)");
20364                    Slog.i(TAG_POWER, sb.toString());
20365                    sb.setLength(0);
20366                    sb.append("CPU for ");
20367                    app.toShortString(sb);
20368                    sb.append(": over ");
20369                    TimeUtils.formatDuration(uptimeSince, sb);
20370                    sb.append(" used ");
20371                    TimeUtils.formatDuration(cputimeUsed, sb);
20372                    sb.append(" (");
20373                    sb.append((cputimeUsed*100)/uptimeSince);
20374                    sb.append("%)");
20375                    Slog.i(TAG_POWER, sb.toString());
20376                }
20377                // If a process has held a wake lock for more
20378                // than 50% of the time during this period,
20379                // that sounds bad.  Kill!
20380                if (doWakeKills && realtimeSince > 0
20381                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
20382                    synchronized (stats) {
20383                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
20384                                realtimeSince, wtimeUsed);
20385                    }
20386                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
20387                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
20388                } else if (doCpuKills && uptimeSince > 0
20389                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
20390                    synchronized (stats) {
20391                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
20392                                uptimeSince, cputimeUsed);
20393                    }
20394                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
20395                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
20396                } else {
20397                    app.lastWakeTime = wtime;
20398                    app.lastCpuTime = app.curCpuTime;
20399                }
20400            }
20401        }
20402    }
20403
20404    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
20405            long nowElapsed) {
20406        boolean success = true;
20407
20408        if (app.curRawAdj != app.setRawAdj) {
20409            app.setRawAdj = app.curRawAdj;
20410        }
20411
20412        int changes = 0;
20413
20414        if (app.curAdj != app.setAdj) {
20415            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
20416            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20417                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
20418                    + app.adjType);
20419            app.setAdj = app.curAdj;
20420            app.verifiedAdj = ProcessList.INVALID_ADJ;
20421        }
20422
20423        if (app.setSchedGroup != app.curSchedGroup) {
20424            int oldSchedGroup = app.setSchedGroup;
20425            app.setSchedGroup = app.curSchedGroup;
20426            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20427                    "Setting sched group of " + app.processName
20428                    + " to " + app.curSchedGroup);
20429            if (app.waitingToKill != null && app.curReceivers.isEmpty()
20430                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
20431                app.kill(app.waitingToKill, true);
20432                success = false;
20433            } else {
20434                int processGroup;
20435                switch (app.curSchedGroup) {
20436                    case ProcessList.SCHED_GROUP_BACKGROUND:
20437                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
20438                        break;
20439                    case ProcessList.SCHED_GROUP_TOP_APP:
20440                    case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
20441                        processGroup = Process.THREAD_GROUP_TOP_APP;
20442                        break;
20443                    default:
20444                        processGroup = Process.THREAD_GROUP_DEFAULT;
20445                        break;
20446                }
20447                long oldId = Binder.clearCallingIdentity();
20448                try {
20449                    Process.setProcessGroup(app.pid, processGroup);
20450                    if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
20451                        // do nothing if we already switched to RT
20452                        if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
20453                            // Switch VR thread for app to SCHED_FIFO
20454                            if (mInVrMode && app.vrThreadTid != 0) {
20455                                try {
20456                                    Process.setThreadScheduler(app.vrThreadTid,
20457                                        Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20458                                } catch (IllegalArgumentException e) {
20459                                    // thread died, ignore
20460                                }
20461                            }
20462                            if (mUseFifoUiScheduling) {
20463                                // Switch UI pipeline for app to SCHED_FIFO
20464                                app.savedPriority = Process.getThreadPriority(app.pid);
20465                                try {
20466                                    Process.setThreadScheduler(app.pid,
20467                                        Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20468                                } catch (IllegalArgumentException e) {
20469                                    // thread died, ignore
20470                                }
20471                                if (app.renderThreadTid != 0) {
20472                                    try {
20473                                        Process.setThreadScheduler(app.renderThreadTid,
20474                                            Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20475                                    } catch (IllegalArgumentException e) {
20476                                        // thread died, ignore
20477                                    }
20478                                    if (DEBUG_OOM_ADJ) {
20479                                        Slog.d("UI_FIFO", "Set RenderThread (TID " +
20480                                            app.renderThreadTid + ") to FIFO");
20481                                    }
20482                                } else {
20483                                    if (DEBUG_OOM_ADJ) {
20484                                        Slog.d("UI_FIFO", "Not setting RenderThread TID");
20485                                    }
20486                                }
20487                            } else {
20488                                // Boost priority for top app UI and render threads
20489                                Process.setThreadPriority(app.pid, -10);
20490                                if (app.renderThreadTid != 0) {
20491                                    try {
20492                                        Process.setThreadPriority(app.renderThreadTid, -10);
20493                                    } catch (IllegalArgumentException e) {
20494                                        // thread died, ignore
20495                                    }
20496                                }
20497                            }
20498                        }
20499                    } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
20500                               app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
20501                        // Reset VR thread to SCHED_OTHER
20502                        // Safe to do even if we're not in VR mode
20503                        if (app.vrThreadTid != 0) {
20504                            Process.setThreadScheduler(app.vrThreadTid, Process.SCHED_OTHER, 0);
20505                        }
20506                        if (mUseFifoUiScheduling) {
20507                            // Reset UI pipeline to SCHED_OTHER
20508                            Process.setThreadScheduler(app.pid, Process.SCHED_OTHER, 0);
20509                            Process.setThreadPriority(app.pid, app.savedPriority);
20510                            if (app.renderThreadTid != 0) {
20511                                Process.setThreadScheduler(app.renderThreadTid,
20512                                    Process.SCHED_OTHER, 0);
20513                                Process.setThreadPriority(app.renderThreadTid, -4);
20514                            }
20515                        } else {
20516                            // Reset priority for top app UI and render threads
20517                            Process.setThreadPriority(app.pid, 0);
20518                            if (app.renderThreadTid != 0) {
20519                                Process.setThreadPriority(app.renderThreadTid, 0);
20520                            }
20521                        }
20522                    }
20523                } catch (Exception e) {
20524                    Slog.w(TAG, "Failed setting process group of " + app.pid
20525                            + " to " + app.curSchedGroup);
20526                    e.printStackTrace();
20527                } finally {
20528                    Binder.restoreCallingIdentity(oldId);
20529                }
20530            }
20531        }
20532        if (app.repForegroundActivities != app.foregroundActivities) {
20533            app.repForegroundActivities = app.foregroundActivities;
20534            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
20535        }
20536        if (app.repProcState != app.curProcState) {
20537            app.repProcState = app.curProcState;
20538            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
20539            if (app.thread != null) {
20540                try {
20541                    if (false) {
20542                        //RuntimeException h = new RuntimeException("here");
20543                        Slog.i(TAG, "Sending new process state " + app.repProcState
20544                                + " to " + app /*, h*/);
20545                    }
20546                    app.thread.setProcessState(app.repProcState);
20547                } catch (RemoteException e) {
20548                }
20549            }
20550        }
20551        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
20552                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
20553            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
20554                // Experimental code to more aggressively collect pss while
20555                // running test...  the problem is that this tends to collect
20556                // the data right when a process is transitioning between process
20557                // states, which well tend to give noisy data.
20558                long start = SystemClock.uptimeMillis();
20559                long pss = Debug.getPss(app.pid, mTmpLong, null);
20560                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
20561                mPendingPssProcesses.remove(app);
20562                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
20563                        + " to " + app.curProcState + ": "
20564                        + (SystemClock.uptimeMillis()-start) + "ms");
20565            }
20566            app.lastStateTime = now;
20567            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20568                    mTestPssMode, isSleepingLocked(), now);
20569            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
20570                    + ProcessList.makeProcStateString(app.setProcState) + " to "
20571                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
20572                    + (app.nextPssTime-now) + ": " + app);
20573        } else {
20574            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
20575                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
20576                    mTestPssMode)))) {
20577                requestPssLocked(app, app.setProcState);
20578                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
20579                        mTestPssMode, isSleepingLocked(), now);
20580            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
20581                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
20582        }
20583        if (app.setProcState != app.curProcState) {
20584            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20585                    "Proc state change of " + app.processName
20586                            + " to " + app.curProcState);
20587            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
20588            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
20589            if (setImportant && !curImportant) {
20590                // This app is no longer something we consider important enough to allow to
20591                // use arbitrary amounts of battery power.  Note
20592                // its current wake lock time to later know to kill it if
20593                // it is not behaving well.
20594                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20595                synchronized (stats) {
20596                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
20597                            app.pid, nowElapsed);
20598                }
20599                app.lastCpuTime = app.curCpuTime;
20600
20601            }
20602            // Inform UsageStats of important process state change
20603            // Must be called before updating setProcState
20604            maybeUpdateUsageStatsLocked(app, nowElapsed);
20605
20606            app.setProcState = app.curProcState;
20607            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20608                app.notCachedSinceIdle = false;
20609            }
20610            if (!doingAll) {
20611                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
20612            } else {
20613                app.procStateChanged = true;
20614            }
20615        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
20616                > USAGE_STATS_INTERACTION_INTERVAL) {
20617            // For apps that sit around for a long time in the interactive state, we need
20618            // to report this at least once a day so they don't go idle.
20619            maybeUpdateUsageStatsLocked(app, nowElapsed);
20620        }
20621
20622        if (changes != 0) {
20623            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20624                    "Changes in " + app + ": " + changes);
20625            int i = mPendingProcessChanges.size()-1;
20626            ProcessChangeItem item = null;
20627            while (i >= 0) {
20628                item = mPendingProcessChanges.get(i);
20629                if (item.pid == app.pid) {
20630                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20631                            "Re-using existing item: " + item);
20632                    break;
20633                }
20634                i--;
20635            }
20636            if (i < 0) {
20637                // No existing item in pending changes; need a new one.
20638                final int NA = mAvailProcessChanges.size();
20639                if (NA > 0) {
20640                    item = mAvailProcessChanges.remove(NA-1);
20641                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20642                            "Retrieving available item: " + item);
20643                } else {
20644                    item = new ProcessChangeItem();
20645                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20646                            "Allocating new item: " + item);
20647                }
20648                item.changes = 0;
20649                item.pid = app.pid;
20650                item.uid = app.info.uid;
20651                if (mPendingProcessChanges.size() == 0) {
20652                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20653                            "*** Enqueueing dispatch processes changed!");
20654                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
20655                }
20656                mPendingProcessChanges.add(item);
20657            }
20658            item.changes |= changes;
20659            item.processState = app.repProcState;
20660            item.foregroundActivities = app.repForegroundActivities;
20661            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20662                    "Item " + Integer.toHexString(System.identityHashCode(item))
20663                    + " " + app.toShortString() + ": changes=" + item.changes
20664                    + " procState=" + item.processState
20665                    + " foreground=" + item.foregroundActivities
20666                    + " type=" + app.adjType + " source=" + app.adjSource
20667                    + " target=" + app.adjTarget);
20668        }
20669
20670        return success;
20671    }
20672
20673    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
20674        final UidRecord.ChangeItem pendingChange;
20675        if (uidRec == null || uidRec.pendingChange == null) {
20676            if (mPendingUidChanges.size() == 0) {
20677                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20678                        "*** Enqueueing dispatch uid changed!");
20679                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
20680            }
20681            final int NA = mAvailUidChanges.size();
20682            if (NA > 0) {
20683                pendingChange = mAvailUidChanges.remove(NA-1);
20684                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20685                        "Retrieving available item: " + pendingChange);
20686            } else {
20687                pendingChange = new UidRecord.ChangeItem();
20688                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20689                        "Allocating new item: " + pendingChange);
20690            }
20691            if (uidRec != null) {
20692                uidRec.pendingChange = pendingChange;
20693                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
20694                    // If this uid is going away, and we haven't yet reported it is gone,
20695                    // then do so now.
20696                    change = UidRecord.CHANGE_GONE_IDLE;
20697                }
20698            } else if (uid < 0) {
20699                throw new IllegalArgumentException("No UidRecord or uid");
20700            }
20701            pendingChange.uidRecord = uidRec;
20702            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
20703            mPendingUidChanges.add(pendingChange);
20704        } else {
20705            pendingChange = uidRec.pendingChange;
20706            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
20707                change = UidRecord.CHANGE_GONE_IDLE;
20708            }
20709        }
20710        pendingChange.change = change;
20711        pendingChange.processState = uidRec != null
20712                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
20713    }
20714
20715    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
20716            String authority) {
20717        if (app == null) return;
20718        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20719            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
20720            if (userState == null) return;
20721            final long now = SystemClock.elapsedRealtime();
20722            Long lastReported = userState.mProviderLastReportedFg.get(authority);
20723            if (lastReported == null || lastReported < now - 60 * 1000L) {
20724                if (mSystemReady) {
20725                    // Cannot touch the user stats if not system ready
20726                    mUsageStatsService.reportContentProviderUsage(
20727                            authority, providerPkgName, app.userId);
20728                }
20729                userState.mProviderLastReportedFg.put(authority, now);
20730            }
20731        }
20732    }
20733
20734    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
20735        if (DEBUG_USAGE_STATS) {
20736            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
20737                    + "] state changes: old = " + app.setProcState + ", new = "
20738                    + app.curProcState);
20739        }
20740        if (mUsageStatsService == null) {
20741            return;
20742        }
20743        boolean isInteraction;
20744        // To avoid some abuse patterns, we are going to be careful about what we consider
20745        // to be an app interaction.  Being the top activity doesn't count while the display
20746        // is sleeping, nor do short foreground services.
20747        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
20748            isInteraction = true;
20749            app.fgInteractionTime = 0;
20750        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
20751            if (app.fgInteractionTime == 0) {
20752                app.fgInteractionTime = nowElapsed;
20753                isInteraction = false;
20754            } else {
20755                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
20756            }
20757        } else {
20758            // If the app was being forced to the foreground, by say a Toast, then
20759            // no need to treat it as an interaction
20760            isInteraction = app.forcingToForeground == null
20761                    && app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20762            app.fgInteractionTime = 0;
20763        }
20764        if (isInteraction && (!app.reportedInteraction
20765                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
20766            app.interactionEventTime = nowElapsed;
20767            String[] packages = app.getPackageList();
20768            if (packages != null) {
20769                for (int i = 0; i < packages.length; i++) {
20770                    mUsageStatsService.reportEvent(packages[i], app.userId,
20771                            UsageEvents.Event.SYSTEM_INTERACTION);
20772                }
20773            }
20774        }
20775        app.reportedInteraction = isInteraction;
20776        if (!isInteraction) {
20777            app.interactionEventTime = 0;
20778        }
20779    }
20780
20781    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
20782        if (proc.thread != null) {
20783            if (proc.baseProcessTracker != null) {
20784                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
20785            }
20786        }
20787    }
20788
20789    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
20790            ProcessRecord TOP_APP, boolean doingAll, long now) {
20791        if (app.thread == null) {
20792            return false;
20793        }
20794
20795        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
20796
20797        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
20798    }
20799
20800    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
20801            boolean oomAdj) {
20802        if (isForeground != proc.foregroundServices) {
20803            proc.foregroundServices = isForeground;
20804            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
20805                    proc.info.uid);
20806            if (isForeground) {
20807                if (curProcs == null) {
20808                    curProcs = new ArrayList<ProcessRecord>();
20809                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
20810                }
20811                if (!curProcs.contains(proc)) {
20812                    curProcs.add(proc);
20813                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
20814                            proc.info.packageName, proc.info.uid);
20815                }
20816            } else {
20817                if (curProcs != null) {
20818                    if (curProcs.remove(proc)) {
20819                        mBatteryStatsService.noteEvent(
20820                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
20821                                proc.info.packageName, proc.info.uid);
20822                        if (curProcs.size() <= 0) {
20823                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
20824                        }
20825                    }
20826                }
20827            }
20828            if (oomAdj) {
20829                updateOomAdjLocked();
20830            }
20831        }
20832    }
20833
20834    private final ActivityRecord resumedAppLocked() {
20835        ActivityRecord act = mStackSupervisor.resumedAppLocked();
20836        String pkg;
20837        int uid;
20838        if (act != null) {
20839            pkg = act.packageName;
20840            uid = act.info.applicationInfo.uid;
20841        } else {
20842            pkg = null;
20843            uid = -1;
20844        }
20845        // Has the UID or resumed package name changed?
20846        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
20847                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
20848            if (mCurResumedPackage != null) {
20849                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
20850                        mCurResumedPackage, mCurResumedUid);
20851            }
20852            mCurResumedPackage = pkg;
20853            mCurResumedUid = uid;
20854            if (mCurResumedPackage != null) {
20855                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
20856                        mCurResumedPackage, mCurResumedUid);
20857            }
20858        }
20859        return act;
20860    }
20861
20862    final boolean updateOomAdjLocked(ProcessRecord app) {
20863        final ActivityRecord TOP_ACT = resumedAppLocked();
20864        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20865        final boolean wasCached = app.cached;
20866
20867        mAdjSeq++;
20868
20869        // This is the desired cached adjusment we want to tell it to use.
20870        // If our app is currently cached, we know it, and that is it.  Otherwise,
20871        // we don't know it yet, and it needs to now be cached we will then
20872        // need to do a complete oom adj.
20873        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
20874                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
20875        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
20876                SystemClock.uptimeMillis());
20877        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
20878            // Changed to/from cached state, so apps after it in the LRU
20879            // list may also be changed.
20880            updateOomAdjLocked();
20881        }
20882        return success;
20883    }
20884
20885    final void updateOomAdjLocked() {
20886        final ActivityRecord TOP_ACT = resumedAppLocked();
20887        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20888        final long now = SystemClock.uptimeMillis();
20889        final long nowElapsed = SystemClock.elapsedRealtime();
20890        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20891        final int N = mLruProcesses.size();
20892
20893        if (false) {
20894            RuntimeException e = new RuntimeException();
20895            e.fillInStackTrace();
20896            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20897        }
20898
20899        // Reset state in all uid records.
20900        for (int i=mActiveUids.size()-1; i>=0; i--) {
20901            final UidRecord uidRec = mActiveUids.valueAt(i);
20902            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20903                    "Starting update of " + uidRec);
20904            uidRec.reset();
20905        }
20906
20907        mStackSupervisor.rankTaskLayersIfNeeded();
20908
20909        mAdjSeq++;
20910        mNewNumServiceProcs = 0;
20911        mNewNumAServiceProcs = 0;
20912
20913        final int emptyProcessLimit;
20914        final int cachedProcessLimit;
20915        if (mProcessLimit <= 0) {
20916            emptyProcessLimit = cachedProcessLimit = 0;
20917        } else if (mProcessLimit == 1) {
20918            emptyProcessLimit = 1;
20919            cachedProcessLimit = 0;
20920        } else {
20921            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20922            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20923        }
20924
20925        // Let's determine how many processes we have running vs.
20926        // how many slots we have for background processes; we may want
20927        // to put multiple processes in a slot of there are enough of
20928        // them.
20929        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20930                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20931        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20932        if (numEmptyProcs > cachedProcessLimit) {
20933            // If there are more empty processes than our limit on cached
20934            // processes, then use the cached process limit for the factor.
20935            // This ensures that the really old empty processes get pushed
20936            // down to the bottom, so if we are running low on memory we will
20937            // have a better chance at keeping around more cached processes
20938            // instead of a gazillion empty processes.
20939            numEmptyProcs = cachedProcessLimit;
20940        }
20941        int emptyFactor = numEmptyProcs/numSlots;
20942        if (emptyFactor < 1) emptyFactor = 1;
20943        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20944        if (cachedFactor < 1) cachedFactor = 1;
20945        int stepCached = 0;
20946        int stepEmpty = 0;
20947        int numCached = 0;
20948        int numEmpty = 0;
20949        int numTrimming = 0;
20950
20951        mNumNonCachedProcs = 0;
20952        mNumCachedHiddenProcs = 0;
20953
20954        // First update the OOM adjustment for each of the
20955        // application processes based on their current state.
20956        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20957        int nextCachedAdj = curCachedAdj+1;
20958        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20959        int nextEmptyAdj = curEmptyAdj+2;
20960        for (int i=N-1; i>=0; i--) {
20961            ProcessRecord app = mLruProcesses.get(i);
20962            if (!app.killedByAm && app.thread != null) {
20963                app.procStateChanged = false;
20964                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20965
20966                // If we haven't yet assigned the final cached adj
20967                // to the process, do that now.
20968                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20969                    switch (app.curProcState) {
20970                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20971                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20972                            // This process is a cached process holding activities...
20973                            // assign it the next cached value for that type, and then
20974                            // step that cached level.
20975                            app.curRawAdj = curCachedAdj;
20976                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20977                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20978                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20979                                    + ")");
20980                            if (curCachedAdj != nextCachedAdj) {
20981                                stepCached++;
20982                                if (stepCached >= cachedFactor) {
20983                                    stepCached = 0;
20984                                    curCachedAdj = nextCachedAdj;
20985                                    nextCachedAdj += 2;
20986                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20987                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20988                                    }
20989                                }
20990                            }
20991                            break;
20992                        default:
20993                            // For everything else, assign next empty cached process
20994                            // level and bump that up.  Note that this means that
20995                            // long-running services that have dropped down to the
20996                            // cached level will be treated as empty (since their process
20997                            // state is still as a service), which is what we want.
20998                            app.curRawAdj = curEmptyAdj;
20999                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
21000                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
21001                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
21002                                    + ")");
21003                            if (curEmptyAdj != nextEmptyAdj) {
21004                                stepEmpty++;
21005                                if (stepEmpty >= emptyFactor) {
21006                                    stepEmpty = 0;
21007                                    curEmptyAdj = nextEmptyAdj;
21008                                    nextEmptyAdj += 2;
21009                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
21010                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
21011                                    }
21012                                }
21013                            }
21014                            break;
21015                    }
21016                }
21017
21018                applyOomAdjLocked(app, true, now, nowElapsed);
21019
21020                // Count the number of process types.
21021                switch (app.curProcState) {
21022                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
21023                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
21024                        mNumCachedHiddenProcs++;
21025                        numCached++;
21026                        if (numCached > cachedProcessLimit) {
21027                            app.kill("cached #" + numCached, true);
21028                        }
21029                        break;
21030                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
21031                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
21032                                && app.lastActivityTime < oldTime) {
21033                            app.kill("empty for "
21034                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
21035                                    / 1000) + "s", true);
21036                        } else {
21037                            numEmpty++;
21038                            if (numEmpty > emptyProcessLimit) {
21039                                app.kill("empty #" + numEmpty, true);
21040                            }
21041                        }
21042                        break;
21043                    default:
21044                        mNumNonCachedProcs++;
21045                        break;
21046                }
21047
21048                if (app.isolated && app.services.size() <= 0) {
21049                    // If this is an isolated process, and there are no
21050                    // services running in it, then the process is no longer
21051                    // needed.  We agressively kill these because we can by
21052                    // definition not re-use the same process again, and it is
21053                    // good to avoid having whatever code was running in them
21054                    // left sitting around after no longer needed.
21055                    app.kill("isolated not needed", true);
21056                } else {
21057                    // Keeping this process, update its uid.
21058                    final UidRecord uidRec = app.uidRecord;
21059                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
21060                        uidRec.curProcState = app.curProcState;
21061                    }
21062                }
21063
21064                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
21065                        && !app.killedByAm) {
21066                    numTrimming++;
21067                }
21068            }
21069        }
21070
21071        mNumServiceProcs = mNewNumServiceProcs;
21072
21073        // Now determine the memory trimming level of background processes.
21074        // Unfortunately we need to start at the back of the list to do this
21075        // properly.  We only do this if the number of background apps we
21076        // are managing to keep around is less than half the maximum we desire;
21077        // if we are keeping a good number around, we'll let them use whatever
21078        // memory they want.
21079        final int numCachedAndEmpty = numCached + numEmpty;
21080        int memFactor;
21081        if (numCached <= ProcessList.TRIM_CACHED_APPS
21082                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
21083            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
21084                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
21085            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
21086                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
21087            } else {
21088                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
21089            }
21090        } else {
21091            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
21092        }
21093        // We always allow the memory level to go up (better).  We only allow it to go
21094        // down if we are in a state where that is allowed, *and* the total number of processes
21095        // has gone down since last time.
21096        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
21097                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
21098                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
21099        if (memFactor > mLastMemoryLevel) {
21100            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
21101                memFactor = mLastMemoryLevel;
21102                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
21103            }
21104        }
21105        if (memFactor != mLastMemoryLevel) {
21106            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
21107        }
21108        mLastMemoryLevel = memFactor;
21109        mLastNumProcesses = mLruProcesses.size();
21110        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
21111        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
21112        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
21113            if (mLowRamStartTime == 0) {
21114                mLowRamStartTime = now;
21115            }
21116            int step = 0;
21117            int fgTrimLevel;
21118            switch (memFactor) {
21119                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
21120                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
21121                    break;
21122                case ProcessStats.ADJ_MEM_FACTOR_LOW:
21123                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
21124                    break;
21125                default:
21126                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
21127                    break;
21128            }
21129            int factor = numTrimming/3;
21130            int minFactor = 2;
21131            if (mHomeProcess != null) minFactor++;
21132            if (mPreviousProcess != null) minFactor++;
21133            if (factor < minFactor) factor = minFactor;
21134            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
21135            for (int i=N-1; i>=0; i--) {
21136                ProcessRecord app = mLruProcesses.get(i);
21137                if (allChanged || app.procStateChanged) {
21138                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
21139                    app.procStateChanged = false;
21140                }
21141                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
21142                        && !app.killedByAm) {
21143                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
21144                        try {
21145                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21146                                    "Trimming memory of " + app.processName + " to " + curLevel);
21147                            app.thread.scheduleTrimMemory(curLevel);
21148                        } catch (RemoteException e) {
21149                        }
21150                        if (false) {
21151                            // For now we won't do this; our memory trimming seems
21152                            // to be good enough at this point that destroying
21153                            // activities causes more harm than good.
21154                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
21155                                    && app != mHomeProcess && app != mPreviousProcess) {
21156                                // Need to do this on its own message because the stack may not
21157                                // be in a consistent state at this point.
21158                                // For these apps we will also finish their activities
21159                                // to help them free memory.
21160                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
21161                            }
21162                        }
21163                    }
21164                    app.trimMemoryLevel = curLevel;
21165                    step++;
21166                    if (step >= factor) {
21167                        step = 0;
21168                        switch (curLevel) {
21169                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
21170                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
21171                                break;
21172                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
21173                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
21174                                break;
21175                        }
21176                    }
21177                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
21178                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
21179                            && app.thread != null) {
21180                        try {
21181                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21182                                    "Trimming memory of heavy-weight " + app.processName
21183                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
21184                            app.thread.scheduleTrimMemory(
21185                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
21186                        } catch (RemoteException e) {
21187                        }
21188                    }
21189                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
21190                } else {
21191                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21192                            || app.systemNoUi) && app.pendingUiClean) {
21193                        // If this application is now in the background and it
21194                        // had done UI, then give it the special trim level to
21195                        // have it free UI resources.
21196                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
21197                        if (app.trimMemoryLevel < level && app.thread != null) {
21198                            try {
21199                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21200                                        "Trimming memory of bg-ui " + app.processName
21201                                        + " to " + level);
21202                                app.thread.scheduleTrimMemory(level);
21203                            } catch (RemoteException e) {
21204                            }
21205                        }
21206                        app.pendingUiClean = false;
21207                    }
21208                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
21209                        try {
21210                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21211                                    "Trimming memory of fg " + app.processName
21212                                    + " to " + fgTrimLevel);
21213                            app.thread.scheduleTrimMemory(fgTrimLevel);
21214                        } catch (RemoteException e) {
21215                        }
21216                    }
21217                    app.trimMemoryLevel = fgTrimLevel;
21218                }
21219            }
21220        } else {
21221            if (mLowRamStartTime != 0) {
21222                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
21223                mLowRamStartTime = 0;
21224            }
21225            for (int i=N-1; i>=0; i--) {
21226                ProcessRecord app = mLruProcesses.get(i);
21227                if (allChanged || app.procStateChanged) {
21228                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
21229                    app.procStateChanged = false;
21230                }
21231                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21232                        || app.systemNoUi) && app.pendingUiClean) {
21233                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
21234                            && app.thread != null) {
21235                        try {
21236                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21237                                    "Trimming memory of ui hidden " + app.processName
21238                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
21239                            app.thread.scheduleTrimMemory(
21240                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
21241                        } catch (RemoteException e) {
21242                        }
21243                    }
21244                    app.pendingUiClean = false;
21245                }
21246                app.trimMemoryLevel = 0;
21247            }
21248        }
21249
21250        if (mAlwaysFinishActivities) {
21251            // Need to do this on its own message because the stack may not
21252            // be in a consistent state at this point.
21253            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
21254        }
21255
21256        if (allChanged) {
21257            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
21258        }
21259
21260        // Update from any uid changes.
21261        for (int i=mActiveUids.size()-1; i>=0; i--) {
21262            final UidRecord uidRec = mActiveUids.valueAt(i);
21263            int uidChange = UidRecord.CHANGE_PROCSTATE;
21264            if (uidRec.setProcState != uidRec.curProcState) {
21265                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21266                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
21267                        + " to " + uidRec.curProcState);
21268                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
21269                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
21270                        uidRec.lastBackgroundTime = nowElapsed;
21271                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
21272                            // Note: the background settle time is in elapsed realtime, while
21273                            // the handler time base is uptime.  All this means is that we may
21274                            // stop background uids later than we had intended, but that only
21275                            // happens because the device was sleeping so we are okay anyway.
21276                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
21277                        }
21278                    }
21279                } else {
21280                    if (uidRec.idle) {
21281                        uidChange = UidRecord.CHANGE_ACTIVE;
21282                        uidRec.idle = false;
21283                    }
21284                    uidRec.lastBackgroundTime = 0;
21285                }
21286                uidRec.setProcState = uidRec.curProcState;
21287                enqueueUidChangeLocked(uidRec, -1, uidChange);
21288                noteUidProcessState(uidRec.uid, uidRec.curProcState);
21289            }
21290        }
21291
21292        if (mProcessStats.shouldWriteNowLocked(now)) {
21293            mHandler.post(new Runnable() {
21294                @Override public void run() {
21295                    synchronized (ActivityManagerService.this) {
21296                        mProcessStats.writeStateAsyncLocked();
21297                    }
21298                }
21299            });
21300        }
21301
21302        if (DEBUG_OOM_ADJ) {
21303            final long duration = SystemClock.uptimeMillis() - now;
21304            if (false) {
21305                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
21306                        new RuntimeException("here").fillInStackTrace());
21307            } else {
21308                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
21309            }
21310        }
21311    }
21312
21313    final void idleUids() {
21314        synchronized (this) {
21315            final long nowElapsed = SystemClock.elapsedRealtime();
21316            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
21317            long nextTime = 0;
21318            for (int i=mActiveUids.size()-1; i>=0; i--) {
21319                final UidRecord uidRec = mActiveUids.valueAt(i);
21320                final long bgTime = uidRec.lastBackgroundTime;
21321                if (bgTime > 0 && !uidRec.idle) {
21322                    if (bgTime <= maxBgTime) {
21323                        uidRec.idle = true;
21324                        doStopUidLocked(uidRec.uid, uidRec);
21325                    } else {
21326                        if (nextTime == 0 || nextTime > bgTime) {
21327                            nextTime = bgTime;
21328                        }
21329                    }
21330                }
21331            }
21332            if (nextTime > 0) {
21333                mHandler.removeMessages(IDLE_UIDS_MSG);
21334                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
21335                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
21336            }
21337        }
21338    }
21339
21340    final void runInBackgroundDisabled(int uid) {
21341        synchronized (this) {
21342            UidRecord uidRec = mActiveUids.get(uid);
21343            if (uidRec != null) {
21344                // This uid is actually running...  should it be considered background now?
21345                if (uidRec.idle) {
21346                    doStopUidLocked(uidRec.uid, uidRec);
21347                }
21348            } else {
21349                // This uid isn't actually running...  still send a report about it being "stopped".
21350                doStopUidLocked(uid, null);
21351            }
21352        }
21353    }
21354
21355    final void doStopUidLocked(int uid, final UidRecord uidRec) {
21356        mServices.stopInBackgroundLocked(uid);
21357        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
21358    }
21359
21360    final void trimApplications() {
21361        synchronized (this) {
21362            int i;
21363
21364            // First remove any unused application processes whose package
21365            // has been removed.
21366            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
21367                final ProcessRecord app = mRemovedProcesses.get(i);
21368                if (app.activities.size() == 0
21369                        && app.curReceivers.isEmpty() && app.services.size() == 0) {
21370                    Slog.i(
21371                        TAG, "Exiting empty application process "
21372                        + app.toShortString() + " ("
21373                        + (app.thread != null ? app.thread.asBinder() : null)
21374                        + ")\n");
21375                    if (app.pid > 0 && app.pid != MY_PID) {
21376                        app.kill("empty", false);
21377                    } else {
21378                        try {
21379                            app.thread.scheduleExit();
21380                        } catch (Exception e) {
21381                            // Ignore exceptions.
21382                        }
21383                    }
21384                    cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
21385                    mRemovedProcesses.remove(i);
21386
21387                    if (app.persistent) {
21388                        addAppLocked(app.info, false, null /* ABI override */);
21389                    }
21390                }
21391            }
21392
21393            // Now update the oom adj for all processes.
21394            updateOomAdjLocked();
21395        }
21396    }
21397
21398    /** This method sends the specified signal to each of the persistent apps */
21399    public void signalPersistentProcesses(int sig) throws RemoteException {
21400        if (sig != Process.SIGNAL_USR1) {
21401            throw new SecurityException("Only SIGNAL_USR1 is allowed");
21402        }
21403
21404        synchronized (this) {
21405            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
21406                    != PackageManager.PERMISSION_GRANTED) {
21407                throw new SecurityException("Requires permission "
21408                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
21409            }
21410
21411            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
21412                ProcessRecord r = mLruProcesses.get(i);
21413                if (r.thread != null && r.persistent) {
21414                    Process.sendSignal(r.pid, sig);
21415                }
21416            }
21417        }
21418    }
21419
21420    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
21421        if (proc == null || proc == mProfileProc) {
21422            proc = mProfileProc;
21423            profileType = mProfileType;
21424            clearProfilerLocked();
21425        }
21426        if (proc == null) {
21427            return;
21428        }
21429        try {
21430            proc.thread.profilerControl(false, null, profileType);
21431        } catch (RemoteException e) {
21432            throw new IllegalStateException("Process disappeared");
21433        }
21434    }
21435
21436    private void clearProfilerLocked() {
21437        if (mProfileFd != null) {
21438            try {
21439                mProfileFd.close();
21440            } catch (IOException e) {
21441            }
21442        }
21443        mProfileApp = null;
21444        mProfileProc = null;
21445        mProfileFile = null;
21446        mProfileType = 0;
21447        mAutoStopProfiler = false;
21448        mStreamingOutput = false;
21449        mSamplingInterval = 0;
21450    }
21451
21452    public boolean profileControl(String process, int userId, boolean start,
21453            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
21454
21455        try {
21456            synchronized (this) {
21457                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21458                // its own permission.
21459                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21460                        != PackageManager.PERMISSION_GRANTED) {
21461                    throw new SecurityException("Requires permission "
21462                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21463                }
21464
21465                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
21466                    throw new IllegalArgumentException("null profile info or fd");
21467                }
21468
21469                ProcessRecord proc = null;
21470                if (process != null) {
21471                    proc = findProcessLocked(process, userId, "profileControl");
21472                }
21473
21474                if (start && (proc == null || proc.thread == null)) {
21475                    throw new IllegalArgumentException("Unknown process: " + process);
21476                }
21477
21478                if (start) {
21479                    stopProfilerLocked(null, 0);
21480                    setProfileApp(proc.info, proc.processName, profilerInfo);
21481                    mProfileProc = proc;
21482                    mProfileType = profileType;
21483                    ParcelFileDescriptor fd = profilerInfo.profileFd;
21484                    try {
21485                        fd = fd.dup();
21486                    } catch (IOException e) {
21487                        fd = null;
21488                    }
21489                    profilerInfo.profileFd = fd;
21490                    proc.thread.profilerControl(start, profilerInfo, profileType);
21491                    fd = null;
21492                    mProfileFd = null;
21493                } else {
21494                    stopProfilerLocked(proc, profileType);
21495                    if (profilerInfo != null && profilerInfo.profileFd != null) {
21496                        try {
21497                            profilerInfo.profileFd.close();
21498                        } catch (IOException e) {
21499                        }
21500                    }
21501                }
21502
21503                return true;
21504            }
21505        } catch (RemoteException e) {
21506            throw new IllegalStateException("Process disappeared");
21507        } finally {
21508            if (profilerInfo != null && profilerInfo.profileFd != null) {
21509                try {
21510                    profilerInfo.profileFd.close();
21511                } catch (IOException e) {
21512                }
21513            }
21514        }
21515    }
21516
21517    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
21518        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
21519                userId, true, ALLOW_FULL_ONLY, callName, null);
21520        ProcessRecord proc = null;
21521        try {
21522            int pid = Integer.parseInt(process);
21523            synchronized (mPidsSelfLocked) {
21524                proc = mPidsSelfLocked.get(pid);
21525            }
21526        } catch (NumberFormatException e) {
21527        }
21528
21529        if (proc == null) {
21530            ArrayMap<String, SparseArray<ProcessRecord>> all
21531                    = mProcessNames.getMap();
21532            SparseArray<ProcessRecord> procs = all.get(process);
21533            if (procs != null && procs.size() > 0) {
21534                proc = procs.valueAt(0);
21535                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
21536                    for (int i=1; i<procs.size(); i++) {
21537                        ProcessRecord thisProc = procs.valueAt(i);
21538                        if (thisProc.userId == userId) {
21539                            proc = thisProc;
21540                            break;
21541                        }
21542                    }
21543                }
21544            }
21545        }
21546
21547        return proc;
21548    }
21549
21550    public boolean dumpHeap(String process, int userId, boolean managed,
21551            String path, ParcelFileDescriptor fd) throws RemoteException {
21552
21553        try {
21554            synchronized (this) {
21555                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21556                // its own permission (same as profileControl).
21557                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21558                        != PackageManager.PERMISSION_GRANTED) {
21559                    throw new SecurityException("Requires permission "
21560                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21561                }
21562
21563                if (fd == null) {
21564                    throw new IllegalArgumentException("null fd");
21565                }
21566
21567                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
21568                if (proc == null || proc.thread == null) {
21569                    throw new IllegalArgumentException("Unknown process: " + process);
21570                }
21571
21572                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21573                if (!isDebuggable) {
21574                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21575                        throw new SecurityException("Process not debuggable: " + proc);
21576                    }
21577                }
21578
21579                proc.thread.dumpHeap(managed, path, fd);
21580                fd = null;
21581                return true;
21582            }
21583        } catch (RemoteException e) {
21584            throw new IllegalStateException("Process disappeared");
21585        } finally {
21586            if (fd != null) {
21587                try {
21588                    fd.close();
21589                } catch (IOException e) {
21590                }
21591            }
21592        }
21593    }
21594
21595    @Override
21596    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
21597            String reportPackage) {
21598        if (processName != null) {
21599            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
21600                    "setDumpHeapDebugLimit()");
21601        } else {
21602            synchronized (mPidsSelfLocked) {
21603                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
21604                if (proc == null) {
21605                    throw new SecurityException("No process found for calling pid "
21606                            + Binder.getCallingPid());
21607                }
21608                if (!Build.IS_DEBUGGABLE
21609                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21610                    throw new SecurityException("Not running a debuggable build");
21611                }
21612                processName = proc.processName;
21613                uid = proc.uid;
21614                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
21615                    throw new SecurityException("Package " + reportPackage + " is not running in "
21616                            + proc);
21617                }
21618            }
21619        }
21620        synchronized (this) {
21621            if (maxMemSize > 0) {
21622                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
21623            } else {
21624                if (uid != 0) {
21625                    mMemWatchProcesses.remove(processName, uid);
21626                } else {
21627                    mMemWatchProcesses.getMap().remove(processName);
21628                }
21629            }
21630        }
21631    }
21632
21633    @Override
21634    public void dumpHeapFinished(String path) {
21635        synchronized (this) {
21636            if (Binder.getCallingPid() != mMemWatchDumpPid) {
21637                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
21638                        + " does not match last pid " + mMemWatchDumpPid);
21639                return;
21640            }
21641            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
21642                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
21643                        + " does not match last path " + mMemWatchDumpFile);
21644                return;
21645            }
21646            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
21647            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
21648        }
21649    }
21650
21651    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
21652    public void monitor() {
21653        synchronized (this) { }
21654    }
21655
21656    void onCoreSettingsChange(Bundle settings) {
21657        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21658            ProcessRecord processRecord = mLruProcesses.get(i);
21659            try {
21660                if (processRecord.thread != null) {
21661                    processRecord.thread.setCoreSettings(settings);
21662                }
21663            } catch (RemoteException re) {
21664                /* ignore */
21665            }
21666        }
21667    }
21668
21669    // Multi-user methods
21670
21671    /**
21672     * Start user, if its not already running, but don't bring it to foreground.
21673     */
21674    @Override
21675    public boolean startUserInBackground(final int userId) {
21676        return mUserController.startUser(userId, /* foreground */ false);
21677    }
21678
21679    @Override
21680    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
21681        return mUserController.unlockUser(userId, token, secret, listener);
21682    }
21683
21684    @Override
21685    public boolean switchUser(final int targetUserId) {
21686        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
21687        UserInfo currentUserInfo;
21688        UserInfo targetUserInfo;
21689        synchronized (this) {
21690            int currentUserId = mUserController.getCurrentUserIdLocked();
21691            currentUserInfo = mUserController.getUserInfo(currentUserId);
21692            targetUserInfo = mUserController.getUserInfo(targetUserId);
21693            if (targetUserInfo == null) {
21694                Slog.w(TAG, "No user info for user #" + targetUserId);
21695                return false;
21696            }
21697            if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
21698                Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
21699                        + " when device is in demo mode");
21700                return false;
21701            }
21702            if (!targetUserInfo.supportsSwitchTo()) {
21703                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
21704                return false;
21705            }
21706            if (targetUserInfo.isManagedProfile()) {
21707                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
21708                return false;
21709            }
21710            mUserController.setTargetUserIdLocked(targetUserId);
21711        }
21712        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
21713        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
21714        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
21715        return true;
21716    }
21717
21718    void scheduleStartProfilesLocked() {
21719        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
21720            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
21721                    DateUtils.SECOND_IN_MILLIS);
21722        }
21723    }
21724
21725    @Override
21726    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
21727        return mUserController.stopUser(userId, force, callback);
21728    }
21729
21730    @Override
21731    public UserInfo getCurrentUser() {
21732        return mUserController.getCurrentUser();
21733    }
21734
21735    @Override
21736    public boolean isUserRunning(int userId, int flags) {
21737        if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
21738                && checkCallingPermission(INTERACT_ACROSS_USERS)
21739                    != PackageManager.PERMISSION_GRANTED) {
21740            String msg = "Permission Denial: isUserRunning() from pid="
21741                    + Binder.getCallingPid()
21742                    + ", uid=" + Binder.getCallingUid()
21743                    + " requires " + INTERACT_ACROSS_USERS;
21744            Slog.w(TAG, msg);
21745            throw new SecurityException(msg);
21746        }
21747        synchronized (this) {
21748            return mUserController.isUserRunningLocked(userId, flags);
21749        }
21750    }
21751
21752    @Override
21753    public int[] getRunningUserIds() {
21754        if (checkCallingPermission(INTERACT_ACROSS_USERS)
21755                != PackageManager.PERMISSION_GRANTED) {
21756            String msg = "Permission Denial: isUserRunning() from pid="
21757                    + Binder.getCallingPid()
21758                    + ", uid=" + Binder.getCallingUid()
21759                    + " requires " + INTERACT_ACROSS_USERS;
21760            Slog.w(TAG, msg);
21761            throw new SecurityException(msg);
21762        }
21763        synchronized (this) {
21764            return mUserController.getStartedUserArrayLocked();
21765        }
21766    }
21767
21768    @Override
21769    public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
21770        mUserController.registerUserSwitchObserver(observer, name);
21771    }
21772
21773    @Override
21774    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
21775        mUserController.unregisterUserSwitchObserver(observer);
21776    }
21777
21778    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
21779        if (info == null) return null;
21780        ApplicationInfo newInfo = new ApplicationInfo(info);
21781        newInfo.initForUser(userId);
21782        return newInfo;
21783    }
21784
21785    public boolean isUserStopped(int userId) {
21786        synchronized (this) {
21787            return mUserController.getStartedUserStateLocked(userId) == null;
21788        }
21789    }
21790
21791    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
21792        if (aInfo == null
21793                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
21794            return aInfo;
21795        }
21796
21797        ActivityInfo info = new ActivityInfo(aInfo);
21798        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
21799        return info;
21800    }
21801
21802    private boolean processSanityChecksLocked(ProcessRecord process) {
21803        if (process == null || process.thread == null) {
21804            return false;
21805        }
21806
21807        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21808        if (!isDebuggable) {
21809            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21810                return false;
21811            }
21812        }
21813
21814        return true;
21815    }
21816
21817    public boolean startBinderTracking() throws RemoteException {
21818        synchronized (this) {
21819            mBinderTransactionTrackingEnabled = true;
21820            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21821            // permission (same as profileControl).
21822            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21823                    != PackageManager.PERMISSION_GRANTED) {
21824                throw new SecurityException("Requires permission "
21825                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21826            }
21827
21828            for (int i = 0; i < mLruProcesses.size(); i++) {
21829                ProcessRecord process = mLruProcesses.get(i);
21830                if (!processSanityChecksLocked(process)) {
21831                    continue;
21832                }
21833                try {
21834                    process.thread.startBinderTracking();
21835                } catch (RemoteException e) {
21836                    Log.v(TAG, "Process disappared");
21837                }
21838            }
21839            return true;
21840        }
21841    }
21842
21843    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
21844        try {
21845            synchronized (this) {
21846                mBinderTransactionTrackingEnabled = false;
21847                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21848                // permission (same as profileControl).
21849                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21850                        != PackageManager.PERMISSION_GRANTED) {
21851                    throw new SecurityException("Requires permission "
21852                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21853                }
21854
21855                if (fd == null) {
21856                    throw new IllegalArgumentException("null fd");
21857                }
21858
21859                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
21860                pw.println("Binder transaction traces for all processes.\n");
21861                for (ProcessRecord process : mLruProcesses) {
21862                    if (!processSanityChecksLocked(process)) {
21863                        continue;
21864                    }
21865
21866                    pw.println("Traces for process: " + process.processName);
21867                    pw.flush();
21868                    try {
21869                        TransferPipe tp = new TransferPipe();
21870                        try {
21871                            process.thread.stopBinderTrackingAndDump(
21872                                    tp.getWriteFd().getFileDescriptor());
21873                            tp.go(fd.getFileDescriptor());
21874                        } finally {
21875                            tp.kill();
21876                        }
21877                    } catch (IOException e) {
21878                        pw.println("Failure while dumping IPC traces from " + process +
21879                                ".  Exception: " + e);
21880                        pw.flush();
21881                    } catch (RemoteException e) {
21882                        pw.println("Got a RemoteException while dumping IPC traces from " +
21883                                process + ".  Exception: " + e);
21884                        pw.flush();
21885                    }
21886                }
21887                fd = null;
21888                return true;
21889            }
21890        } finally {
21891            if (fd != null) {
21892                try {
21893                    fd.close();
21894                } catch (IOException e) {
21895                }
21896            }
21897        }
21898    }
21899
21900    private final class LocalService extends ActivityManagerInternal {
21901        @Override
21902        public void onWakefulnessChanged(int wakefulness) {
21903            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21904        }
21905
21906        @Override
21907        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21908                String processName, String abiOverride, int uid, Runnable crashHandler) {
21909            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21910                    processName, abiOverride, uid, crashHandler);
21911        }
21912
21913        @Override
21914        public SleepToken acquireSleepToken(String tag) {
21915            Preconditions.checkNotNull(tag);
21916
21917            ComponentName requestedVrService = null;
21918            ComponentName callingVrActivity = null;
21919            int userId = -1;
21920            synchronized (ActivityManagerService.this) {
21921                if (mFocusedActivity != null) {
21922                    requestedVrService = mFocusedActivity.requestedVrComponent;
21923                    callingVrActivity = mFocusedActivity.info.getComponentName();
21924                    userId = mFocusedActivity.userId;
21925                }
21926            }
21927
21928            if (requestedVrService != null) {
21929                applyVrMode(false, requestedVrService, userId, callingVrActivity, true);
21930            }
21931
21932            synchronized (ActivityManagerService.this) {
21933                SleepTokenImpl token = new SleepTokenImpl(tag);
21934                mSleepTokens.add(token);
21935                updateSleepIfNeededLocked();
21936                return token;
21937            }
21938        }
21939
21940        @Override
21941        public ComponentName getHomeActivityForUser(int userId) {
21942            synchronized (ActivityManagerService.this) {
21943                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21944                return homeActivity == null ? null : homeActivity.realActivity;
21945            }
21946        }
21947
21948        @Override
21949        public void onUserRemoved(int userId) {
21950            synchronized (ActivityManagerService.this) {
21951                ActivityManagerService.this.onUserStoppedLocked(userId);
21952            }
21953        }
21954
21955        @Override
21956        public void onLocalVoiceInteractionStarted(IBinder activity,
21957                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
21958            synchronized (ActivityManagerService.this) {
21959                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21960                        voiceSession, voiceInteractor);
21961            }
21962        }
21963
21964        @Override
21965        public void notifyStartingWindowDrawn() {
21966            synchronized (ActivityManagerService.this) {
21967                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
21968            }
21969        }
21970
21971        @Override
21972        public void notifyAppTransitionStarting(int reason) {
21973            synchronized (ActivityManagerService.this) {
21974                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
21975            }
21976        }
21977
21978        @Override
21979        public void notifyAppTransitionFinished() {
21980            synchronized (ActivityManagerService.this) {
21981                mStackSupervisor.notifyAppTransitionDone();
21982            }
21983        }
21984
21985        @Override
21986        public void notifyAppTransitionCancelled() {
21987            synchronized (ActivityManagerService.this) {
21988                mStackSupervisor.notifyAppTransitionDone();
21989            }
21990        }
21991
21992        @Override
21993        public List<IBinder> getTopVisibleActivities() {
21994            synchronized (ActivityManagerService.this) {
21995                return mStackSupervisor.getTopVisibleActivities();
21996            }
21997        }
21998
21999        @Override
22000        public void notifyDockedStackMinimizedChanged(boolean minimized) {
22001            synchronized (ActivityManagerService.this) {
22002                mStackSupervisor.setDockedStackMinimized(minimized);
22003            }
22004        }
22005
22006        @Override
22007        public void killForegroundAppsForUser(int userHandle) {
22008            synchronized (ActivityManagerService.this) {
22009                final ArrayList<ProcessRecord> procs = new ArrayList<>();
22010                final int NP = mProcessNames.getMap().size();
22011                for (int ip = 0; ip < NP; ip++) {
22012                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
22013                    final int NA = apps.size();
22014                    for (int ia = 0; ia < NA; ia++) {
22015                        final ProcessRecord app = apps.valueAt(ia);
22016                        if (app.persistent) {
22017                            // We don't kill persistent processes.
22018                            continue;
22019                        }
22020                        if (app.removed) {
22021                            procs.add(app);
22022                        } else if (app.userId == userHandle && app.foregroundActivities) {
22023                            app.removed = true;
22024                            procs.add(app);
22025                        }
22026                    }
22027                }
22028
22029                final int N = procs.size();
22030                for (int i = 0; i < N; i++) {
22031                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
22032                }
22033            }
22034        }
22035
22036        @Override
22037        public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
22038            if (!(target instanceof PendingIntentRecord)) {
22039                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
22040                return;
22041            }
22042            ((PendingIntentRecord) target).setWhitelistDuration(duration);
22043        }
22044
22045        @Override
22046        public void updatePersistentConfigurationForUser(@NonNull Configuration values,
22047                int userId) {
22048            Preconditions.checkNotNull(values, "Configuration must not be null");
22049            Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
22050            synchronized (ActivityManagerService.this) {
22051                updateConfigurationLocked(values, null, false, true, userId,
22052                        false /* deferResume */);
22053            }
22054        }
22055
22056        @Override
22057        public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
22058                Bundle bOptions) {
22059            Preconditions.checkNotNull(intents, "intents");
22060            final String[] resolvedTypes = new String[intents.length];
22061            for (int i = 0; i < intents.length; i++) {
22062                resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
22063            }
22064
22065            // UID of the package on user userId.
22066            // "= 0" is needed because otherwise catch(RemoteException) would make it look like
22067            // packageUid may not be initialized.
22068            int packageUid = 0;
22069            try {
22070                packageUid = AppGlobals.getPackageManager().getPackageUid(
22071                        packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
22072            } catch (RemoteException e) {
22073                // Shouldn't happen.
22074            }
22075
22076            synchronized (ActivityManagerService.this) {
22077                return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
22078                        /*resultTo*/ null, bOptions, userId);
22079            }
22080        }
22081
22082        @Override
22083        public int getUidProcessState(int uid) {
22084            return getUidState(uid);
22085        }
22086    }
22087
22088    private final class SleepTokenImpl extends SleepToken {
22089        private final String mTag;
22090        private final long mAcquireTime;
22091
22092        public SleepTokenImpl(String tag) {
22093            mTag = tag;
22094            mAcquireTime = SystemClock.uptimeMillis();
22095        }
22096
22097        @Override
22098        public void release() {
22099            synchronized (ActivityManagerService.this) {
22100                if (mSleepTokens.remove(this)) {
22101                    updateSleepIfNeededLocked();
22102                }
22103            }
22104        }
22105
22106        @Override
22107        public String toString() {
22108            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
22109        }
22110    }
22111
22112    /**
22113     * An implementation of IAppTask, that allows an app to manage its own tasks via
22114     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
22115     * only the process that calls getAppTasks() can call the AppTask methods.
22116     */
22117    class AppTaskImpl extends IAppTask.Stub {
22118        private int mTaskId;
22119        private int mCallingUid;
22120
22121        public AppTaskImpl(int taskId, int callingUid) {
22122            mTaskId = taskId;
22123            mCallingUid = callingUid;
22124        }
22125
22126        private void checkCaller() {
22127            if (mCallingUid != Binder.getCallingUid()) {
22128                throw new SecurityException("Caller " + mCallingUid
22129                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
22130            }
22131        }
22132
22133        @Override
22134        public void finishAndRemoveTask() {
22135            checkCaller();
22136
22137            synchronized (ActivityManagerService.this) {
22138                long origId = Binder.clearCallingIdentity();
22139                try {
22140                    // We remove the task from recents to preserve backwards
22141                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
22142                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22143                    }
22144                } finally {
22145                    Binder.restoreCallingIdentity(origId);
22146                }
22147            }
22148        }
22149
22150        @Override
22151        public ActivityManager.RecentTaskInfo getTaskInfo() {
22152            checkCaller();
22153
22154            synchronized (ActivityManagerService.this) {
22155                long origId = Binder.clearCallingIdentity();
22156                try {
22157                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22158                    if (tr == null) {
22159                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22160                    }
22161                    return createRecentTaskInfoFromTaskRecord(tr);
22162                } finally {
22163                    Binder.restoreCallingIdentity(origId);
22164                }
22165            }
22166        }
22167
22168        @Override
22169        public void moveToFront() {
22170            checkCaller();
22171            // Will bring task to front if it already has a root activity.
22172            final long origId = Binder.clearCallingIdentity();
22173            try {
22174                synchronized (this) {
22175                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
22176                }
22177            } finally {
22178                Binder.restoreCallingIdentity(origId);
22179            }
22180        }
22181
22182        @Override
22183        public int startActivity(IBinder whoThread, String callingPackage,
22184                Intent intent, String resolvedType, Bundle bOptions) {
22185            checkCaller();
22186
22187            int callingUser = UserHandle.getCallingUserId();
22188            TaskRecord tr;
22189            IApplicationThread appThread;
22190            synchronized (ActivityManagerService.this) {
22191                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22192                if (tr == null) {
22193                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22194                }
22195                appThread = ApplicationThreadNative.asInterface(whoThread);
22196                if (appThread == null) {
22197                    throw new IllegalArgumentException("Bad app thread " + appThread);
22198                }
22199            }
22200            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
22201                    resolvedType, null, null, null, null, 0, 0, null, null,
22202                    null, bOptions, false, callingUser, null, tr);
22203        }
22204
22205        @Override
22206        public void setExcludeFromRecents(boolean exclude) {
22207            checkCaller();
22208
22209            synchronized (ActivityManagerService.this) {
22210                long origId = Binder.clearCallingIdentity();
22211                try {
22212                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22213                    if (tr == null) {
22214                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22215                    }
22216                    Intent intent = tr.getBaseIntent();
22217                    if (exclude) {
22218                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
22219                    } else {
22220                        intent.setFlags(intent.getFlags()
22221                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
22222                    }
22223                } finally {
22224                    Binder.restoreCallingIdentity(origId);
22225                }
22226            }
22227        }
22228    }
22229
22230    /**
22231     * Kill processes for the user with id userId and that depend on the package named packageName
22232     */
22233    @Override
22234    public void killPackageDependents(String packageName, int userId) {
22235        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
22236        if (packageName == null) {
22237            throw new NullPointerException(
22238                    "Cannot kill the dependents of a package without its name.");
22239        }
22240
22241        long callingId = Binder.clearCallingIdentity();
22242        IPackageManager pm = AppGlobals.getPackageManager();
22243        int pkgUid = -1;
22244        try {
22245            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
22246        } catch (RemoteException e) {
22247        }
22248        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
22249            throw new IllegalArgumentException(
22250                    "Cannot kill dependents of non-existing package " + packageName);
22251        }
22252        try {
22253            synchronized(this) {
22254                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
22255                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
22256                        "dep: " + packageName);
22257            }
22258        } finally {
22259            Binder.restoreCallingIdentity(callingId);
22260        }
22261    }
22262
22263    @Override
22264    public boolean canBypassWorkChallenge(PendingIntent intent) throws RemoteException {
22265        final int userId = intent.getCreatorUserHandle().getIdentifier();
22266        if (!mUserController.isUserRunningLocked(userId, ActivityManager.FLAG_AND_LOCKED)) {
22267            return false;
22268        }
22269        IIntentSender target = intent.getTarget();
22270        if (!(target instanceof PendingIntentRecord)) {
22271            return false;
22272        }
22273        final PendingIntentRecord record = (PendingIntentRecord) target;
22274        final ResolveInfo rInfo = mStackSupervisor.resolveIntent(record.key.requestIntent,
22275                record.key.requestResolvedType, userId, PackageManager.MATCH_DIRECT_BOOT_AWARE);
22276        // For direct boot aware activities, they can be shown without triggering a work challenge
22277        // before the profile user is unlocked.
22278        return rInfo != null && rInfo.activityInfo != null;
22279    }
22280}
22281