ActivityManagerService.java revision 347b1df98890f843b41123ff3a08e483a4b966f9
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    int mProfileType = 0;
1385    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1386    String mMemWatchDumpProcName;
1387    String mMemWatchDumpFile;
1388    int mMemWatchDumpPid;
1389    int mMemWatchDumpUid;
1390    String mTrackAllocationApp = null;
1391    String mNativeDebuggingApp = null;
1392
1393    final long[] mTmpLong = new long[2];
1394
1395    static final class ProcessChangeItem {
1396        static final int CHANGE_ACTIVITIES = 1<<0;
1397        static final int CHANGE_PROCESS_STATE = 1<<1;
1398        int changes;
1399        int uid;
1400        int pid;
1401        int processState;
1402        boolean foregroundActivities;
1403    }
1404
1405    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1406    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1407
1408    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1409    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1410
1411    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1412    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1413
1414    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1415    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1416
1417    /**
1418     * Runtime CPU use collection thread.  This object's lock is used to
1419     * perform synchronization with the thread (notifying it to run).
1420     */
1421    final Thread mProcessCpuThread;
1422
1423    /**
1424     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1425     * Must acquire this object's lock when accessing it.
1426     * NOTE: this lock will be held while doing long operations (trawling
1427     * through all processes in /proc), so it should never be acquired by
1428     * any critical paths such as when holding the main activity manager lock.
1429     */
1430    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1431            MONITOR_THREAD_CPU_USAGE);
1432    final AtomicLong mLastCpuTime = new AtomicLong(0);
1433    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1434
1435    long mLastWriteTime = 0;
1436
1437    /**
1438     * Used to retain an update lock when the foreground activity is in
1439     * immersive mode.
1440     */
1441    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1442
1443    /**
1444     * Set to true after the system has finished booting.
1445     */
1446    boolean mBooted = false;
1447
1448    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1449    int mProcessLimitOverride = -1;
1450
1451    WindowManagerService mWindowManager;
1452    final ActivityThread mSystemThread;
1453
1454    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1455        final ProcessRecord mApp;
1456        final int mPid;
1457        final IApplicationThread mAppThread;
1458
1459        AppDeathRecipient(ProcessRecord app, int pid,
1460                IApplicationThread thread) {
1461            if (DEBUG_ALL) Slog.v(
1462                TAG, "New death recipient " + this
1463                + " for thread " + thread.asBinder());
1464            mApp = app;
1465            mPid = pid;
1466            mAppThread = thread;
1467        }
1468
1469        @Override
1470        public void binderDied() {
1471            if (DEBUG_ALL) Slog.v(
1472                TAG, "Death received in " + this
1473                + " for thread " + mAppThread.asBinder());
1474            synchronized(ActivityManagerService.this) {
1475                appDiedLocked(mApp, mPid, mAppThread, true);
1476            }
1477        }
1478    }
1479
1480    static final int SHOW_ERROR_UI_MSG = 1;
1481    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1482    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1483    static final int UPDATE_CONFIGURATION_MSG = 4;
1484    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1485    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1486    static final int SERVICE_TIMEOUT_MSG = 12;
1487    static final int UPDATE_TIME_ZONE = 13;
1488    static final int SHOW_UID_ERROR_UI_MSG = 14;
1489    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1490    static final int PROC_START_TIMEOUT_MSG = 20;
1491    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1492    static final int KILL_APPLICATION_MSG = 22;
1493    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1494    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1495    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1496    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1497    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1498    static final int CLEAR_DNS_CACHE_MSG = 28;
1499    static final int UPDATE_HTTP_PROXY_MSG = 29;
1500    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1501    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1502    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1503    static final int REPORT_MEM_USAGE_MSG = 33;
1504    static final int REPORT_USER_SWITCH_MSG = 34;
1505    static final int CONTINUE_USER_SWITCH_MSG = 35;
1506    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1507    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1508    static final int PERSIST_URI_GRANTS_MSG = 38;
1509    static final int REQUEST_ALL_PSS_MSG = 39;
1510    static final int START_PROFILES_MSG = 40;
1511    static final int UPDATE_TIME = 41;
1512    static final int SYSTEM_USER_START_MSG = 42;
1513    static final int SYSTEM_USER_CURRENT_MSG = 43;
1514    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1515    static final int FINISH_BOOTING_MSG = 45;
1516    static final int START_USER_SWITCH_UI_MSG = 46;
1517    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1518    static final int DISMISS_DIALOG_UI_MSG = 48;
1519    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1520    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1521    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1522    static final int DELETE_DUMPHEAP_MSG = 52;
1523    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1524    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1525    static final int REPORT_TIME_TRACKER_MSG = 55;
1526    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1527    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1528    static final int APP_BOOST_DEACTIVATE_MSG = 58;
1529    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1530    static final int IDLE_UIDS_MSG = 60;
1531    static final int SYSTEM_USER_UNLOCK_MSG = 61;
1532    static final int LOG_STACK_STATE = 62;
1533    static final int VR_MODE_CHANGE_MSG = 63;
1534    static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1535    static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1536    static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1537    static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
1538    static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
1539    static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
1540    static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 70;
1541
1542    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1543    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1544    static final int FIRST_COMPAT_MODE_MSG = 300;
1545    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1546
1547    static ServiceThread sKillThread = null;
1548    static KillHandler sKillHandler = null;
1549
1550    CompatModeDialog mCompatModeDialog;
1551    UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1552    long mLastMemUsageReportTime = 0;
1553
1554    /**
1555     * Flag whether the current user is a "monkey", i.e. whether
1556     * the UI is driven by a UI automation tool.
1557     */
1558    private boolean mUserIsMonkey;
1559
1560    /** Flag whether the device has a Recents UI */
1561    boolean mHasRecents;
1562
1563    /** The dimensions of the thumbnails in the Recents UI. */
1564    int mThumbnailWidth;
1565    int mThumbnailHeight;
1566    float mFullscreenThumbnailScale;
1567
1568    final ServiceThread mHandlerThread;
1569    final MainHandler mHandler;
1570    final UiHandler mUiHandler;
1571
1572    PackageManagerInternal mPackageManagerInt;
1573
1574    // VoiceInteraction session ID that changes for each new request except when
1575    // being called for multiwindow assist in a single session.
1576    private int mViSessionId = 1000;
1577
1578    final boolean mPermissionReviewRequired;
1579
1580    final class KillHandler extends Handler {
1581        static final int KILL_PROCESS_GROUP_MSG = 4000;
1582
1583        public KillHandler(Looper looper) {
1584            super(looper, null, true);
1585        }
1586
1587        @Override
1588        public void handleMessage(Message msg) {
1589            switch (msg.what) {
1590                case KILL_PROCESS_GROUP_MSG:
1591                {
1592                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1593                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1594                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1595                }
1596                break;
1597
1598                default:
1599                    super.handleMessage(msg);
1600            }
1601        }
1602    }
1603
1604    final class UiHandler extends Handler {
1605        public UiHandler() {
1606            super(com.android.server.UiThread.get().getLooper(), null, true);
1607        }
1608
1609        @Override
1610        public void handleMessage(Message msg) {
1611            switch (msg.what) {
1612            case SHOW_ERROR_UI_MSG: {
1613                mAppErrors.handleShowAppErrorUi(msg);
1614                ensureBootCompleted();
1615            } break;
1616            case SHOW_NOT_RESPONDING_UI_MSG: {
1617                mAppErrors.handleShowAnrUi(msg);
1618                ensureBootCompleted();
1619            } break;
1620            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1621                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1622                synchronized (ActivityManagerService.this) {
1623                    ProcessRecord proc = (ProcessRecord) data.get("app");
1624                    if (proc == null) {
1625                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1626                        break;
1627                    }
1628                    if (proc.crashDialog != null) {
1629                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1630                        return;
1631                    }
1632                    AppErrorResult res = (AppErrorResult) data.get("result");
1633                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1634                        Dialog d = new StrictModeViolationDialog(mContext,
1635                                ActivityManagerService.this, res, proc);
1636                        d.show();
1637                        proc.crashDialog = d;
1638                    } else {
1639                        // The device is asleep, so just pretend that the user
1640                        // saw a crash dialog and hit "force quit".
1641                        res.set(0);
1642                    }
1643                }
1644                ensureBootCompleted();
1645            } break;
1646            case SHOW_FACTORY_ERROR_UI_MSG: {
1647                Dialog d = new FactoryErrorDialog(
1648                    mContext, msg.getData().getCharSequence("msg"));
1649                d.show();
1650                ensureBootCompleted();
1651            } break;
1652            case WAIT_FOR_DEBUGGER_UI_MSG: {
1653                synchronized (ActivityManagerService.this) {
1654                    ProcessRecord app = (ProcessRecord)msg.obj;
1655                    if (msg.arg1 != 0) {
1656                        if (!app.waitedForDebugger) {
1657                            Dialog d = new AppWaitingForDebuggerDialog(
1658                                    ActivityManagerService.this,
1659                                    mContext, app);
1660                            app.waitDialog = d;
1661                            app.waitedForDebugger = true;
1662                            d.show();
1663                        }
1664                    } else {
1665                        if (app.waitDialog != null) {
1666                            app.waitDialog.dismiss();
1667                            app.waitDialog = null;
1668                        }
1669                    }
1670                }
1671            } break;
1672            case SHOW_UID_ERROR_UI_MSG: {
1673                if (mShowDialogs) {
1674                    AlertDialog d = new BaseErrorDialog(mContext);
1675                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1676                    d.setCancelable(false);
1677                    d.setTitle(mContext.getText(R.string.android_system_label));
1678                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1679                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1680                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1681                    d.show();
1682                }
1683            } break;
1684            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1685                if (mShowDialogs) {
1686                    AlertDialog d = new BaseErrorDialog(mContext);
1687                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1688                    d.setCancelable(false);
1689                    d.setTitle(mContext.getText(R.string.android_system_label));
1690                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1691                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1692                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1693                    d.show();
1694                }
1695            } break;
1696            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1697                synchronized (ActivityManagerService.this) {
1698                    ActivityRecord ar = (ActivityRecord) msg.obj;
1699                    if (mCompatModeDialog != null) {
1700                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1701                                ar.info.applicationInfo.packageName)) {
1702                            return;
1703                        }
1704                        mCompatModeDialog.dismiss();
1705                        mCompatModeDialog = null;
1706                    }
1707                    if (ar != null && false) {
1708                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1709                                ar.packageName)) {
1710                            int mode = mCompatModePackages.computeCompatModeLocked(
1711                                    ar.info.applicationInfo);
1712                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1713                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1714                                mCompatModeDialog = new CompatModeDialog(
1715                                        ActivityManagerService.this, mContext,
1716                                        ar.info.applicationInfo);
1717                                mCompatModeDialog.show();
1718                            }
1719                        }
1720                    }
1721                }
1722                break;
1723            }
1724            case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1725                synchronized (ActivityManagerService.this) {
1726                    final ActivityRecord ar = (ActivityRecord) msg.obj;
1727                    if (mUnsupportedDisplaySizeDialog != null) {
1728                        mUnsupportedDisplaySizeDialog.dismiss();
1729                        mUnsupportedDisplaySizeDialog = null;
1730                    }
1731                    if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1732                            ar.packageName)) {
1733                        mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1734                                ActivityManagerService.this, mContext, ar.info.applicationInfo);
1735                        mUnsupportedDisplaySizeDialog.show();
1736                    }
1737                }
1738                break;
1739            }
1740            case START_USER_SWITCH_UI_MSG: {
1741                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1742                break;
1743            }
1744            case DISMISS_DIALOG_UI_MSG: {
1745                final Dialog d = (Dialog) msg.obj;
1746                d.dismiss();
1747                break;
1748            }
1749            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1750                dispatchProcessesChanged();
1751                break;
1752            }
1753            case DISPATCH_PROCESS_DIED_UI_MSG: {
1754                final int pid = msg.arg1;
1755                final int uid = msg.arg2;
1756                dispatchProcessDied(pid, uid);
1757                break;
1758            }
1759            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1760                dispatchUidsChanged();
1761            } break;
1762            }
1763        }
1764    }
1765
1766    final class MainHandler extends Handler {
1767        public MainHandler(Looper looper) {
1768            super(looper, null, true);
1769        }
1770
1771        @Override
1772        public void handleMessage(Message msg) {
1773            switch (msg.what) {
1774            case UPDATE_CONFIGURATION_MSG: {
1775                final ContentResolver resolver = mContext.getContentResolver();
1776                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1777                        msg.arg1);
1778            } break;
1779            case GC_BACKGROUND_PROCESSES_MSG: {
1780                synchronized (ActivityManagerService.this) {
1781                    performAppGcsIfAppropriateLocked();
1782                }
1783            } break;
1784            case SERVICE_TIMEOUT_MSG: {
1785                if (mDidDexOpt) {
1786                    mDidDexOpt = false;
1787                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1788                    nmsg.obj = msg.obj;
1789                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1790                    return;
1791                }
1792                mServices.serviceTimeout((ProcessRecord)msg.obj);
1793            } break;
1794            case UPDATE_TIME_ZONE: {
1795                synchronized (ActivityManagerService.this) {
1796                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1797                        ProcessRecord r = mLruProcesses.get(i);
1798                        if (r.thread != null) {
1799                            try {
1800                                r.thread.updateTimeZone();
1801                            } catch (RemoteException ex) {
1802                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1803                            }
1804                        }
1805                    }
1806                }
1807            } break;
1808            case CLEAR_DNS_CACHE_MSG: {
1809                synchronized (ActivityManagerService.this) {
1810                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1811                        ProcessRecord r = mLruProcesses.get(i);
1812                        if (r.thread != null) {
1813                            try {
1814                                r.thread.clearDnsCache();
1815                            } catch (RemoteException ex) {
1816                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1817                            }
1818                        }
1819                    }
1820                }
1821            } break;
1822            case UPDATE_HTTP_PROXY_MSG: {
1823                ProxyInfo proxy = (ProxyInfo)msg.obj;
1824                String host = "";
1825                String port = "";
1826                String exclList = "";
1827                Uri pacFileUrl = Uri.EMPTY;
1828                if (proxy != null) {
1829                    host = proxy.getHost();
1830                    port = Integer.toString(proxy.getPort());
1831                    exclList = proxy.getExclusionListAsString();
1832                    pacFileUrl = proxy.getPacFileUrl();
1833                }
1834                synchronized (ActivityManagerService.this) {
1835                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1836                        ProcessRecord r = mLruProcesses.get(i);
1837                        if (r.thread != null) {
1838                            try {
1839                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1840                            } catch (RemoteException ex) {
1841                                Slog.w(TAG, "Failed to update http proxy for: " +
1842                                        r.info.processName);
1843                            }
1844                        }
1845                    }
1846                }
1847            } break;
1848            case PROC_START_TIMEOUT_MSG: {
1849                if (mDidDexOpt) {
1850                    mDidDexOpt = false;
1851                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1852                    nmsg.obj = msg.obj;
1853                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1854                    return;
1855                }
1856                ProcessRecord app = (ProcessRecord)msg.obj;
1857                synchronized (ActivityManagerService.this) {
1858                    processStartTimedOutLocked(app);
1859                }
1860            } break;
1861            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1862                ProcessRecord app = (ProcessRecord)msg.obj;
1863                synchronized (ActivityManagerService.this) {
1864                    processContentProviderPublishTimedOutLocked(app);
1865                }
1866            } break;
1867            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1868                synchronized (ActivityManagerService.this) {
1869                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1870                }
1871            } break;
1872            case KILL_APPLICATION_MSG: {
1873                synchronized (ActivityManagerService.this) {
1874                    final int appId = msg.arg1;
1875                    final int userId = msg.arg2;
1876                    Bundle bundle = (Bundle)msg.obj;
1877                    String pkg = bundle.getString("pkg");
1878                    String reason = bundle.getString("reason");
1879                    forceStopPackageLocked(pkg, appId, false, false, true, false,
1880                            false, userId, reason);
1881                }
1882            } break;
1883            case FINALIZE_PENDING_INTENT_MSG: {
1884                ((PendingIntentRecord)msg.obj).completeFinalize();
1885            } break;
1886            case POST_HEAVY_NOTIFICATION_MSG: {
1887                INotificationManager inm = NotificationManager.getService();
1888                if (inm == null) {
1889                    return;
1890                }
1891
1892                ActivityRecord root = (ActivityRecord)msg.obj;
1893                ProcessRecord process = root.app;
1894                if (process == null) {
1895                    return;
1896                }
1897
1898                try {
1899                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1900                    String text = mContext.getString(R.string.heavy_weight_notification,
1901                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1902                    Notification notification = new Notification.Builder(context)
1903                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1904                            .setWhen(0)
1905                            .setOngoing(true)
1906                            .setTicker(text)
1907                            .setColor(mContext.getColor(
1908                                    com.android.internal.R.color.system_notification_accent_color))
1909                            .setContentTitle(text)
1910                            .setContentText(
1911                                    mContext.getText(R.string.heavy_weight_notification_detail))
1912                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1913                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1914                                    new UserHandle(root.userId)))
1915                            .build();
1916                    try {
1917                        int[] outId = new int[1];
1918                        inm.enqueueNotificationWithTag("android", "android", null,
1919                                R.string.heavy_weight_notification,
1920                                notification, outId, root.userId);
1921                    } catch (RuntimeException e) {
1922                        Slog.w(ActivityManagerService.TAG,
1923                                "Error showing notification for heavy-weight app", e);
1924                    } catch (RemoteException e) {
1925                    }
1926                } catch (NameNotFoundException e) {
1927                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1928                }
1929            } break;
1930            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1931                INotificationManager inm = NotificationManager.getService();
1932                if (inm == null) {
1933                    return;
1934                }
1935                try {
1936                    inm.cancelNotificationWithTag("android", null,
1937                            R.string.heavy_weight_notification,  msg.arg1);
1938                } catch (RuntimeException e) {
1939                    Slog.w(ActivityManagerService.TAG,
1940                            "Error canceling notification for service", e);
1941                } catch (RemoteException e) {
1942                }
1943            } break;
1944            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1945                synchronized (ActivityManagerService.this) {
1946                    checkExcessivePowerUsageLocked(true);
1947                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1948                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1949                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1950                }
1951            } break;
1952            case REPORT_MEM_USAGE_MSG: {
1953                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1954                Thread thread = new Thread() {
1955                    @Override public void run() {
1956                        reportMemUsage(memInfos);
1957                    }
1958                };
1959                thread.start();
1960                break;
1961            }
1962            case REPORT_USER_SWITCH_MSG: {
1963                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1964                break;
1965            }
1966            case CONTINUE_USER_SWITCH_MSG: {
1967                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1968                break;
1969            }
1970            case USER_SWITCH_TIMEOUT_MSG: {
1971                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1972                break;
1973            }
1974            case IMMERSIVE_MODE_LOCK_MSG: {
1975                final boolean nextState = (msg.arg1 != 0);
1976                if (mUpdateLock.isHeld() != nextState) {
1977                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1978                            "Applying new update lock state '" + nextState
1979                            + "' for " + (ActivityRecord)msg.obj);
1980                    if (nextState) {
1981                        mUpdateLock.acquire();
1982                    } else {
1983                        mUpdateLock.release();
1984                    }
1985                }
1986                break;
1987            }
1988            case PERSIST_URI_GRANTS_MSG: {
1989                writeGrantedUriPermissions();
1990                break;
1991            }
1992            case REQUEST_ALL_PSS_MSG: {
1993                synchronized (ActivityManagerService.this) {
1994                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1995                }
1996                break;
1997            }
1998            case START_PROFILES_MSG: {
1999                synchronized (ActivityManagerService.this) {
2000                    mUserController.startProfilesLocked();
2001                }
2002                break;
2003            }
2004            case UPDATE_TIME: {
2005                synchronized (ActivityManagerService.this) {
2006                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2007                        ProcessRecord r = mLruProcesses.get(i);
2008                        if (r.thread != null) {
2009                            try {
2010                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
2011                            } catch (RemoteException ex) {
2012                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
2013                            }
2014                        }
2015                    }
2016                }
2017                break;
2018            }
2019            case SYSTEM_USER_START_MSG: {
2020                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2021                        Integer.toString(msg.arg1), msg.arg1);
2022                mSystemServiceManager.startUser(msg.arg1);
2023                break;
2024            }
2025            case SYSTEM_USER_UNLOCK_MSG: {
2026                final int userId = msg.arg1;
2027                mSystemServiceManager.unlockUser(userId);
2028                synchronized (ActivityManagerService.this) {
2029                    mRecentTasks.loadUserRecentsLocked(userId);
2030                }
2031                if (userId == UserHandle.USER_SYSTEM) {
2032                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2033                }
2034                installEncryptionUnawareProviders(userId);
2035                mUserController.finishUserUnlocked((UserState) msg.obj);
2036                break;
2037            }
2038            case SYSTEM_USER_CURRENT_MSG: {
2039                mBatteryStatsService.noteEvent(
2040                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2041                        Integer.toString(msg.arg2), msg.arg2);
2042                mBatteryStatsService.noteEvent(
2043                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2044                        Integer.toString(msg.arg1), msg.arg1);
2045                mSystemServiceManager.switchUser(msg.arg1);
2046                break;
2047            }
2048            case ENTER_ANIMATION_COMPLETE_MSG: {
2049                synchronized (ActivityManagerService.this) {
2050                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2051                    if (r != null && r.app != null && r.app.thread != null) {
2052                        try {
2053                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2054                        } catch (RemoteException e) {
2055                        }
2056                    }
2057                }
2058                break;
2059            }
2060            case FINISH_BOOTING_MSG: {
2061                if (msg.arg1 != 0) {
2062                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2063                    finishBooting();
2064                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2065                }
2066                if (msg.arg2 != 0) {
2067                    enableScreenAfterBoot();
2068                }
2069                break;
2070            }
2071            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2072                try {
2073                    Locale l = (Locale) msg.obj;
2074                    IBinder service = ServiceManager.getService("mount");
2075                    IMountService mountService = IMountService.Stub.asInterface(service);
2076                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2077                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2078                } catch (RemoteException e) {
2079                    Log.e(TAG, "Error storing locale for decryption UI", e);
2080                }
2081                break;
2082            }
2083            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
2084                synchronized (ActivityManagerService.this) {
2085                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2086                        try {
2087                            // Make a one-way callback to the listener
2088                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
2089                        } catch (RemoteException e){
2090                            // Handled by the RemoteCallbackList
2091                        }
2092                    }
2093                    mTaskStackListeners.finishBroadcast();
2094                }
2095                break;
2096            }
2097            case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
2098                synchronized (ActivityManagerService.this) {
2099                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2100                        try {
2101                            // Make a one-way callback to the listener
2102                            mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
2103                        } catch (RemoteException e){
2104                            // Handled by the RemoteCallbackList
2105                        }
2106                    }
2107                    mTaskStackListeners.finishBroadcast();
2108                }
2109                break;
2110            }
2111            case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
2112                synchronized (ActivityManagerService.this) {
2113                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2114                        try {
2115                            // Make a one-way callback to the listener
2116                            mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
2117                        } catch (RemoteException e){
2118                            // Handled by the RemoteCallbackList
2119                        }
2120                    }
2121                    mTaskStackListeners.finishBroadcast();
2122                }
2123                break;
2124            }
2125            case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2126                synchronized (ActivityManagerService.this) {
2127                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2128                        try {
2129                            // Make a one-way callback to the listener
2130                            mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2131                        } catch (RemoteException e){
2132                            // Handled by the RemoteCallbackList
2133                        }
2134                    }
2135                    mTaskStackListeners.finishBroadcast();
2136                }
2137                break;
2138            }
2139            case NOTIFY_FORCED_RESIZABLE_MSG: {
2140                synchronized (ActivityManagerService.this) {
2141                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2142                        try {
2143                            // Make a one-way callback to the listener
2144                            mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
2145                                    (String) msg.obj, msg.arg1);
2146                        } catch (RemoteException e){
2147                            // Handled by the RemoteCallbackList
2148                        }
2149                    }
2150                    mTaskStackListeners.finishBroadcast();
2151                }
2152                break;
2153            }
2154                case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
2155                    synchronized (ActivityManagerService.this) {
2156                        for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2157                            try {
2158                                // Make a one-way callback to the listener
2159                                mTaskStackListeners.getBroadcastItem(i)
2160                                        .onActivityDismissingDockedStack();
2161                            } catch (RemoteException e){
2162                                // Handled by the RemoteCallbackList
2163                            }
2164                        }
2165                        mTaskStackListeners.finishBroadcast();
2166                    }
2167                    break;
2168                }
2169            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2170                final int uid = msg.arg1;
2171                final byte[] firstPacket = (byte[]) msg.obj;
2172
2173                synchronized (mPidsSelfLocked) {
2174                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2175                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2176                        if (p.uid == uid) {
2177                            try {
2178                                p.thread.notifyCleartextNetwork(firstPacket);
2179                            } catch (RemoteException ignored) {
2180                            }
2181                        }
2182                    }
2183                }
2184                break;
2185            }
2186            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2187                final String procName;
2188                final int uid;
2189                final long memLimit;
2190                final String reportPackage;
2191                synchronized (ActivityManagerService.this) {
2192                    procName = mMemWatchDumpProcName;
2193                    uid = mMemWatchDumpUid;
2194                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2195                    if (val == null) {
2196                        val = mMemWatchProcesses.get(procName, 0);
2197                    }
2198                    if (val != null) {
2199                        memLimit = val.first;
2200                        reportPackage = val.second;
2201                    } else {
2202                        memLimit = 0;
2203                        reportPackage = null;
2204                    }
2205                }
2206                if (procName == null) {
2207                    return;
2208                }
2209
2210                if (DEBUG_PSS) Slog.d(TAG_PSS,
2211                        "Showing dump heap notification from " + procName + "/" + uid);
2212
2213                INotificationManager inm = NotificationManager.getService();
2214                if (inm == null) {
2215                    return;
2216                }
2217
2218                String text = mContext.getString(R.string.dump_heap_notification, procName);
2219
2220
2221                Intent deleteIntent = new Intent();
2222                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2223                Intent intent = new Intent();
2224                intent.setClassName("android", DumpHeapActivity.class.getName());
2225                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2226                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2227                if (reportPackage != null) {
2228                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2229                }
2230                int userId = UserHandle.getUserId(uid);
2231                Notification notification = new Notification.Builder(mContext)
2232                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2233                        .setWhen(0)
2234                        .setOngoing(true)
2235                        .setAutoCancel(true)
2236                        .setTicker(text)
2237                        .setColor(mContext.getColor(
2238                                com.android.internal.R.color.system_notification_accent_color))
2239                        .setContentTitle(text)
2240                        .setContentText(
2241                                mContext.getText(R.string.dump_heap_notification_detail))
2242                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2243                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2244                                new UserHandle(userId)))
2245                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2246                                deleteIntent, 0, UserHandle.SYSTEM))
2247                        .build();
2248
2249                try {
2250                    int[] outId = new int[1];
2251                    inm.enqueueNotificationWithTag("android", "android", null,
2252                            R.string.dump_heap_notification,
2253                            notification, outId, userId);
2254                } catch (RuntimeException e) {
2255                    Slog.w(ActivityManagerService.TAG,
2256                            "Error showing notification for dump heap", e);
2257                } catch (RemoteException e) {
2258                }
2259            } break;
2260            case DELETE_DUMPHEAP_MSG: {
2261                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2262                        DumpHeapActivity.JAVA_URI,
2263                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2264                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2265                        UserHandle.myUserId());
2266                synchronized (ActivityManagerService.this) {
2267                    mMemWatchDumpFile = null;
2268                    mMemWatchDumpProcName = null;
2269                    mMemWatchDumpPid = -1;
2270                    mMemWatchDumpUid = -1;
2271                }
2272            } break;
2273            case FOREGROUND_PROFILE_CHANGED_MSG: {
2274                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2275            } break;
2276            case REPORT_TIME_TRACKER_MSG: {
2277                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2278                tracker.deliverResult(mContext);
2279            } break;
2280            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2281                mUserController.dispatchUserSwitchComplete(msg.arg1);
2282            } break;
2283            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2284                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2285                try {
2286                    connection.shutdown();
2287                } catch (RemoteException e) {
2288                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2289                }
2290                // Only a UiAutomation can set this flag and now that
2291                // it is finished we make sure it is reset to its default.
2292                mUserIsMonkey = false;
2293            } break;
2294            case APP_BOOST_DEACTIVATE_MSG: {
2295                synchronized(ActivityManagerService.this) {
2296                    if (mIsBoosted) {
2297                        if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2298                            nativeMigrateFromBoost();
2299                            mIsBoosted = false;
2300                            mBoostStartTime = 0;
2301                        } else {
2302                            Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2303                            mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2304                        }
2305                    }
2306                }
2307            } break;
2308            case IDLE_UIDS_MSG: {
2309                idleUids();
2310            } break;
2311            case LOG_STACK_STATE: {
2312                synchronized (ActivityManagerService.this) {
2313                    mStackSupervisor.logStackState();
2314                }
2315            } break;
2316            case VR_MODE_CHANGE_MSG: {
2317                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2318                if (vrService == null) {
2319                    break;
2320                }
2321                final ActivityRecord r = (ActivityRecord) msg.obj;
2322                boolean vrMode;
2323                ComponentName requestedPackage;
2324                ComponentName callingPackage;
2325                int userId;
2326                synchronized (ActivityManagerService.this) {
2327                    vrMode = r.requestedVrComponent != null;
2328                    requestedPackage = r.requestedVrComponent;
2329                    userId = r.userId;
2330                    callingPackage = r.info.getComponentName();
2331                    if (mInVrMode != vrMode) {
2332                        mInVrMode = vrMode;
2333                        mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2334                        if (r.app != null) {
2335                            ProcessRecord proc = r.app;
2336                            if (proc.vrThreadTid > 0) {
2337                                if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
2338                                    try {
2339                                        if (mInVrMode == true) {
2340                                            Process.setThreadScheduler(proc.vrThreadTid,
2341                                                Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
2342                                        } else {
2343                                            Process.setThreadScheduler(proc.vrThreadTid,
2344                                                Process.SCHED_OTHER, 0);
2345                                        }
2346                                    } catch (IllegalArgumentException e) {
2347                                        Slog.w(TAG, "Failed to set scheduling policy, thread does"
2348                                                + " not exist:\n" + e);
2349                                    }
2350                                }
2351                            }
2352                        }
2353                    }
2354                }
2355                vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2356            } break;
2357            case VR_MODE_APPLY_IF_NEEDED_MSG: {
2358                final ActivityRecord r = (ActivityRecord) msg.obj;
2359                final boolean needsVrMode = r != null && r.requestedVrComponent != null;
2360                if (needsVrMode) {
2361                    applyVrMode(msg.arg1 == 1, r.requestedVrComponent, r.userId,
2362                            r.info.getComponentName(), false);
2363                }
2364            } break;
2365            }
2366        }
2367    };
2368
2369    static final int COLLECT_PSS_BG_MSG = 1;
2370
2371    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2372        @Override
2373        public void handleMessage(Message msg) {
2374            switch (msg.what) {
2375            case COLLECT_PSS_BG_MSG: {
2376                long start = SystemClock.uptimeMillis();
2377                MemInfoReader memInfo = null;
2378                synchronized (ActivityManagerService.this) {
2379                    if (mFullPssPending) {
2380                        mFullPssPending = false;
2381                        memInfo = new MemInfoReader();
2382                    }
2383                }
2384                if (memInfo != null) {
2385                    updateCpuStatsNow();
2386                    long nativeTotalPss = 0;
2387                    final List<ProcessCpuTracker.Stats> stats;
2388                    synchronized (mProcessCpuTracker) {
2389                        stats = mProcessCpuTracker.getStats( (st)-> {
2390                            return st.vsize > 0 && st.uid < Process.FIRST_APPLICATION_UID;
2391                        });
2392                    }
2393                    final int N = stats.size();
2394                    for (int j = 0; j < N; j++) {
2395                        synchronized (mPidsSelfLocked) {
2396                            if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
2397                                // This is one of our own processes; skip it.
2398                                continue;
2399                            }
2400                        }
2401                        nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
2402                    }
2403                    memInfo.readMemInfo();
2404                    synchronized (ActivityManagerService.this) {
2405                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2406                                + (SystemClock.uptimeMillis()-start) + "ms");
2407                        final long cachedKb = memInfo.getCachedSizeKb();
2408                        final long freeKb = memInfo.getFreeSizeKb();
2409                        final long zramKb = memInfo.getZramTotalSizeKb();
2410                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2411                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2412                                kernelKb*1024, nativeTotalPss*1024);
2413                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2414                                nativeTotalPss);
2415                    }
2416                }
2417
2418                int num = 0;
2419                long[] tmp = new long[2];
2420                do {
2421                    ProcessRecord proc;
2422                    int procState;
2423                    int pid;
2424                    long lastPssTime;
2425                    synchronized (ActivityManagerService.this) {
2426                        if (mPendingPssProcesses.size() <= 0) {
2427                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2428                                    "Collected PSS of " + num + " processes in "
2429                                    + (SystemClock.uptimeMillis() - start) + "ms");
2430                            mPendingPssProcesses.clear();
2431                            return;
2432                        }
2433                        proc = mPendingPssProcesses.remove(0);
2434                        procState = proc.pssProcState;
2435                        lastPssTime = proc.lastPssTime;
2436                        if (proc.thread != null && procState == proc.setProcState
2437                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2438                                        < SystemClock.uptimeMillis()) {
2439                            pid = proc.pid;
2440                        } else {
2441                            proc = null;
2442                            pid = 0;
2443                        }
2444                    }
2445                    if (proc != null) {
2446                        long pss = Debug.getPss(pid, tmp, null);
2447                        synchronized (ActivityManagerService.this) {
2448                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2449                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2450                                num++;
2451                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2452                                        SystemClock.uptimeMillis());
2453                            }
2454                        }
2455                    }
2456                } while (true);
2457            }
2458            }
2459        }
2460    };
2461
2462    public void setSystemProcess() {
2463        try {
2464            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2465            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2466            ServiceManager.addService("meminfo", new MemBinder(this));
2467            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2468            ServiceManager.addService("dbinfo", new DbBinder(this));
2469            if (MONITOR_CPU_USAGE) {
2470                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2471            }
2472            ServiceManager.addService("permission", new PermissionController(this));
2473            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2474
2475            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2476                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2477            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2478
2479            synchronized (this) {
2480                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2481                app.persistent = true;
2482                app.pid = MY_PID;
2483                app.maxAdj = ProcessList.SYSTEM_ADJ;
2484                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2485                synchronized (mPidsSelfLocked) {
2486                    mPidsSelfLocked.put(app.pid, app);
2487                }
2488                updateLruProcessLocked(app, false, null);
2489                updateOomAdjLocked();
2490            }
2491        } catch (PackageManager.NameNotFoundException e) {
2492            throw new RuntimeException(
2493                    "Unable to find android system package", e);
2494        }
2495    }
2496
2497    public void setWindowManager(WindowManagerService wm) {
2498        mWindowManager = wm;
2499        mStackSupervisor.setWindowManager(wm);
2500        mActivityStarter.setWindowManager(wm);
2501    }
2502
2503    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2504        mUsageStatsService = usageStatsManager;
2505    }
2506
2507    public void startObservingNativeCrashes() {
2508        final NativeCrashListener ncl = new NativeCrashListener(this);
2509        ncl.start();
2510    }
2511
2512    public IAppOpsService getAppOpsService() {
2513        return mAppOpsService;
2514    }
2515
2516    static class MemBinder extends Binder {
2517        ActivityManagerService mActivityManagerService;
2518        MemBinder(ActivityManagerService activityManagerService) {
2519            mActivityManagerService = activityManagerService;
2520        }
2521
2522        @Override
2523        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2524            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2525                    != PackageManager.PERMISSION_GRANTED) {
2526                pw.println("Permission Denial: can't dump meminfo from from pid="
2527                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2528                        + " without permission " + android.Manifest.permission.DUMP);
2529                return;
2530            }
2531
2532            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2533        }
2534    }
2535
2536    static class GraphicsBinder extends Binder {
2537        ActivityManagerService mActivityManagerService;
2538        GraphicsBinder(ActivityManagerService activityManagerService) {
2539            mActivityManagerService = activityManagerService;
2540        }
2541
2542        @Override
2543        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2544            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2545                    != PackageManager.PERMISSION_GRANTED) {
2546                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2547                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2548                        + " without permission " + android.Manifest.permission.DUMP);
2549                return;
2550            }
2551
2552            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2553        }
2554    }
2555
2556    static class DbBinder extends Binder {
2557        ActivityManagerService mActivityManagerService;
2558        DbBinder(ActivityManagerService activityManagerService) {
2559            mActivityManagerService = activityManagerService;
2560        }
2561
2562        @Override
2563        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2564            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2565                    != PackageManager.PERMISSION_GRANTED) {
2566                pw.println("Permission Denial: can't dump dbinfo from from pid="
2567                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2568                        + " without permission " + android.Manifest.permission.DUMP);
2569                return;
2570            }
2571
2572            mActivityManagerService.dumpDbInfo(fd, pw, args);
2573        }
2574    }
2575
2576    static class CpuBinder extends Binder {
2577        ActivityManagerService mActivityManagerService;
2578        CpuBinder(ActivityManagerService activityManagerService) {
2579            mActivityManagerService = activityManagerService;
2580        }
2581
2582        @Override
2583        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2584            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2585                    != PackageManager.PERMISSION_GRANTED) {
2586                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2587                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2588                        + " without permission " + android.Manifest.permission.DUMP);
2589                return;
2590            }
2591
2592            synchronized (mActivityManagerService.mProcessCpuTracker) {
2593                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2594                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2595                        SystemClock.uptimeMillis()));
2596            }
2597        }
2598    }
2599
2600    public static final class Lifecycle extends SystemService {
2601        private final ActivityManagerService mService;
2602
2603        public Lifecycle(Context context) {
2604            super(context);
2605            mService = new ActivityManagerService(context);
2606        }
2607
2608        @Override
2609        public void onStart() {
2610            mService.start();
2611        }
2612
2613        public ActivityManagerService getService() {
2614            return mService;
2615        }
2616    }
2617
2618    // Note: This method is invoked on the main thread but may need to attach various
2619    // handlers to other threads.  So take care to be explicit about the looper.
2620    public ActivityManagerService(Context systemContext) {
2621        mContext = systemContext;
2622        mFactoryTest = FactoryTest.getMode();
2623        mSystemThread = ActivityThread.currentActivityThread();
2624
2625        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2626
2627        mPermissionReviewRequired = mContext.getResources().getBoolean(
2628                com.android.internal.R.bool.config_permissionReviewRequired);
2629
2630        mHandlerThread = new ServiceThread(TAG,
2631                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2632        mHandlerThread.start();
2633        mHandler = new MainHandler(mHandlerThread.getLooper());
2634        mUiHandler = new UiHandler();
2635
2636        /* static; one-time init here */
2637        if (sKillHandler == null) {
2638            sKillThread = new ServiceThread(TAG + ":kill",
2639                    android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2640            sKillThread.start();
2641            sKillHandler = new KillHandler(sKillThread.getLooper());
2642        }
2643
2644        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2645                "foreground", BROADCAST_FG_TIMEOUT, false);
2646        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2647                "background", BROADCAST_BG_TIMEOUT, true);
2648        mBroadcastQueues[0] = mFgBroadcastQueue;
2649        mBroadcastQueues[1] = mBgBroadcastQueue;
2650
2651        mServices = new ActiveServices(this);
2652        mProviderMap = new ProviderMap(this);
2653        mAppErrors = new AppErrors(mContext, this);
2654
2655        // TODO: Move creation of battery stats service outside of activity manager service.
2656        File dataDir = Environment.getDataDirectory();
2657        File systemDir = new File(dataDir, "system");
2658        systemDir.mkdirs();
2659        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2660        mBatteryStatsService.getActiveStatistics().readLocked();
2661        mBatteryStatsService.scheduleWriteToDisk();
2662        mOnBattery = DEBUG_POWER ? true
2663                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2664        mBatteryStatsService.getActiveStatistics().setCallback(this);
2665
2666        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2667
2668        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2669        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2670                new IAppOpsCallback.Stub() {
2671                    @Override public void opChanged(int op, int uid, String packageName) {
2672                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2673                            if (mAppOpsService.checkOperation(op, uid, packageName)
2674                                    != AppOpsManager.MODE_ALLOWED) {
2675                                runInBackgroundDisabled(uid);
2676                            }
2677                        }
2678                    }
2679                });
2680
2681        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2682
2683        mUserController = new UserController(this);
2684
2685        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2686            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2687
2688        if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
2689            mUseFifoUiScheduling = true;
2690        }
2691
2692        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2693
2694        mConfiguration.setToDefaults();
2695        mConfiguration.setLocales(LocaleList.getDefault());
2696
2697        mConfigurationSeq = mConfiguration.seq = 1;
2698        mProcessCpuTracker.init();
2699
2700        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2701        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2702        mStackSupervisor = new ActivityStackSupervisor(this);
2703        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2704        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2705
2706        mProcessCpuThread = new Thread("CpuTracker") {
2707            @Override
2708            public void run() {
2709                while (true) {
2710                    try {
2711                        try {
2712                            synchronized(this) {
2713                                final long now = SystemClock.uptimeMillis();
2714                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2715                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2716                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2717                                //        + ", write delay=" + nextWriteDelay);
2718                                if (nextWriteDelay < nextCpuDelay) {
2719                                    nextCpuDelay = nextWriteDelay;
2720                                }
2721                                if (nextCpuDelay > 0) {
2722                                    mProcessCpuMutexFree.set(true);
2723                                    this.wait(nextCpuDelay);
2724                                }
2725                            }
2726                        } catch (InterruptedException e) {
2727                        }
2728                        updateCpuStatsNow();
2729                    } catch (Exception e) {
2730                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2731                    }
2732                }
2733            }
2734        };
2735
2736        Watchdog.getInstance().addMonitor(this);
2737        Watchdog.getInstance().addThread(mHandler);
2738    }
2739
2740    public void setSystemServiceManager(SystemServiceManager mgr) {
2741        mSystemServiceManager = mgr;
2742    }
2743
2744    public void setInstaller(Installer installer) {
2745        mInstaller = installer;
2746    }
2747
2748    private void start() {
2749        Process.removeAllProcessGroups();
2750        mProcessCpuThread.start();
2751
2752        mBatteryStatsService.publish(mContext);
2753        mAppOpsService.publish(mContext);
2754        Slog.d("AppOps", "AppOpsService published");
2755        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2756    }
2757
2758    void onUserStoppedLocked(int userId) {
2759        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2760    }
2761
2762    public void initPowerManagement() {
2763        mStackSupervisor.initPowerManagement();
2764        mBatteryStatsService.initPowerManagement();
2765        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2766        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2767        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2768        mVoiceWakeLock.setReferenceCounted(false);
2769    }
2770
2771    @Override
2772    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2773            throws RemoteException {
2774        if (code == SYSPROPS_TRANSACTION) {
2775            // We need to tell all apps about the system property change.
2776            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2777            synchronized(this) {
2778                final int NP = mProcessNames.getMap().size();
2779                for (int ip=0; ip<NP; ip++) {
2780                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2781                    final int NA = apps.size();
2782                    for (int ia=0; ia<NA; ia++) {
2783                        ProcessRecord app = apps.valueAt(ia);
2784                        if (app.thread != null) {
2785                            procs.add(app.thread.asBinder());
2786                        }
2787                    }
2788                }
2789            }
2790
2791            int N = procs.size();
2792            for (int i=0; i<N; i++) {
2793                Parcel data2 = Parcel.obtain();
2794                try {
2795                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2796                } catch (RemoteException e) {
2797                }
2798                data2.recycle();
2799            }
2800        }
2801        try {
2802            return super.onTransact(code, data, reply, flags);
2803        } catch (RuntimeException e) {
2804            // The activity manager only throws security exceptions, so let's
2805            // log all others.
2806            if (!(e instanceof SecurityException)) {
2807                Slog.wtf(TAG, "Activity Manager Crash", e);
2808            }
2809            throw e;
2810        }
2811    }
2812
2813    void updateCpuStats() {
2814        final long now = SystemClock.uptimeMillis();
2815        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2816            return;
2817        }
2818        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2819            synchronized (mProcessCpuThread) {
2820                mProcessCpuThread.notify();
2821            }
2822        }
2823    }
2824
2825    void updateCpuStatsNow() {
2826        synchronized (mProcessCpuTracker) {
2827            mProcessCpuMutexFree.set(false);
2828            final long now = SystemClock.uptimeMillis();
2829            boolean haveNewCpuStats = false;
2830
2831            if (MONITOR_CPU_USAGE &&
2832                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2833                mLastCpuTime.set(now);
2834                mProcessCpuTracker.update();
2835                if (mProcessCpuTracker.hasGoodLastStats()) {
2836                    haveNewCpuStats = true;
2837                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2838                    //Slog.i(TAG, "Total CPU usage: "
2839                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2840
2841                    // Slog the cpu usage if the property is set.
2842                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2843                        int user = mProcessCpuTracker.getLastUserTime();
2844                        int system = mProcessCpuTracker.getLastSystemTime();
2845                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2846                        int irq = mProcessCpuTracker.getLastIrqTime();
2847                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2848                        int idle = mProcessCpuTracker.getLastIdleTime();
2849
2850                        int total = user + system + iowait + irq + softIrq + idle;
2851                        if (total == 0) total = 1;
2852
2853                        EventLog.writeEvent(EventLogTags.CPU,
2854                                ((user+system+iowait+irq+softIrq) * 100) / total,
2855                                (user * 100) / total,
2856                                (system * 100) / total,
2857                                (iowait * 100) / total,
2858                                (irq * 100) / total,
2859                                (softIrq * 100) / total);
2860                    }
2861                }
2862            }
2863
2864            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2865            synchronized(bstats) {
2866                synchronized(mPidsSelfLocked) {
2867                    if (haveNewCpuStats) {
2868                        if (bstats.startAddingCpuLocked()) {
2869                            int totalUTime = 0;
2870                            int totalSTime = 0;
2871                            final int N = mProcessCpuTracker.countStats();
2872                            for (int i=0; i<N; i++) {
2873                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2874                                if (!st.working) {
2875                                    continue;
2876                                }
2877                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2878                                totalUTime += st.rel_utime;
2879                                totalSTime += st.rel_stime;
2880                                if (pr != null) {
2881                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2882                                    if (ps == null || !ps.isActive()) {
2883                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2884                                                pr.info.uid, pr.processName);
2885                                    }
2886                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2887                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2888                                } else {
2889                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2890                                    if (ps == null || !ps.isActive()) {
2891                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2892                                                bstats.mapUid(st.uid), st.name);
2893                                    }
2894                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2895                                }
2896                            }
2897                            final int userTime = mProcessCpuTracker.getLastUserTime();
2898                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2899                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2900                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2901                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2902                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2903                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2904                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2905                        }
2906                    }
2907                }
2908
2909                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2910                    mLastWriteTime = now;
2911                    mBatteryStatsService.scheduleWriteToDisk();
2912                }
2913            }
2914        }
2915    }
2916
2917    @Override
2918    public void batteryNeedsCpuUpdate() {
2919        updateCpuStatsNow();
2920    }
2921
2922    @Override
2923    public void batteryPowerChanged(boolean onBattery) {
2924        // When plugging in, update the CPU stats first before changing
2925        // the plug state.
2926        updateCpuStatsNow();
2927        synchronized (this) {
2928            synchronized(mPidsSelfLocked) {
2929                mOnBattery = DEBUG_POWER ? true : onBattery;
2930            }
2931        }
2932    }
2933
2934    @Override
2935    public void batterySendBroadcast(Intent intent) {
2936        synchronized (this) {
2937            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2938                    AppOpsManager.OP_NONE, null, false, false,
2939                    -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2940        }
2941    }
2942
2943    /**
2944     * Initialize the application bind args. These are passed to each
2945     * process when the bindApplication() IPC is sent to the process. They're
2946     * lazily setup to make sure the services are running when they're asked for.
2947     */
2948    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2949        // Isolated processes won't get this optimization, so that we don't
2950        // violate the rules about which services they have access to.
2951        if (isolated) {
2952            if (mIsolatedAppBindArgs == null) {
2953                mIsolatedAppBindArgs = new HashMap<>();
2954                mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
2955            }
2956            return mIsolatedAppBindArgs;
2957        }
2958
2959        if (mAppBindArgs == null) {
2960            mAppBindArgs = new HashMap<>();
2961
2962            // Setup the application init args
2963            mAppBindArgs.put("package", ServiceManager.getService("package"));
2964            mAppBindArgs.put("window", ServiceManager.getService("window"));
2965            mAppBindArgs.put(Context.ALARM_SERVICE,
2966                    ServiceManager.getService(Context.ALARM_SERVICE));
2967        }
2968        return mAppBindArgs;
2969    }
2970
2971    boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2972        if (r == null || mFocusedActivity == r) {
2973            return false;
2974        }
2975
2976        if (!r.isFocusable()) {
2977            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2978            return false;
2979        }
2980
2981        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2982
2983        final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2984        if (wasDoingSetFocusedActivity) Slog.w(TAG,
2985                "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2986        mDoingSetFocusedActivity = true;
2987
2988        final ActivityRecord last = mFocusedActivity;
2989        mFocusedActivity = r;
2990        if (r.task.isApplicationTask()) {
2991            if (mCurAppTimeTracker != r.appTimeTracker) {
2992                // We are switching app tracking.  Complete the current one.
2993                if (mCurAppTimeTracker != null) {
2994                    mCurAppTimeTracker.stop();
2995                    mHandler.obtainMessage(
2996                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2997                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2998                    mCurAppTimeTracker = null;
2999                }
3000                if (r.appTimeTracker != null) {
3001                    mCurAppTimeTracker = r.appTimeTracker;
3002                    startTimeTrackingFocusedActivityLocked();
3003                }
3004            } else {
3005                startTimeTrackingFocusedActivityLocked();
3006            }
3007        } else {
3008            r.appTimeTracker = null;
3009        }
3010        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
3011        // TODO: Probably not, because we don't want to resume voice on switching
3012        // back to this activity
3013        if (r.task.voiceInteractor != null) {
3014            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
3015        } else {
3016            finishRunningVoiceLocked();
3017            IVoiceInteractionSession session;
3018            if (last != null && ((session = last.task.voiceSession) != null
3019                    || (session = last.voiceSession) != null)) {
3020                // We had been in a voice interaction session, but now focused has
3021                // move to something different.  Just finish the session, we can't
3022                // return to it and retain the proper state and synchronization with
3023                // the voice interaction service.
3024                finishVoiceTask(session);
3025            }
3026        }
3027        if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
3028            mWindowManager.setFocusedApp(r.appToken, true);
3029        }
3030        applyUpdateLockStateLocked(r);
3031        applyUpdateVrModeLocked(r);
3032        if (mFocusedActivity.userId != mLastFocusedUserId) {
3033            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3034            mHandler.obtainMessage(
3035                    FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
3036            mLastFocusedUserId = mFocusedActivity.userId;
3037        }
3038
3039        // Log a warning if the focused app is changed during the process. This could
3040        // indicate a problem of the focus setting logic!
3041        if (mFocusedActivity != r) Slog.w(TAG,
3042                "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
3043        mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
3044
3045        EventLogTags.writeAmFocusedActivity(
3046                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
3047                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
3048                reason);
3049        return true;
3050    }
3051
3052    final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
3053        if (mFocusedActivity != goingAway) {
3054            return;
3055        }
3056
3057        final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
3058        if (focusedStack != null) {
3059            final ActivityRecord top = focusedStack.topActivity();
3060            if (top != null && top.userId != mLastFocusedUserId) {
3061                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3062                mHandler.sendMessage(
3063                        mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
3064                mLastFocusedUserId = top.userId;
3065            }
3066        }
3067
3068        // Try to move focus to another activity if possible.
3069        if (setFocusedActivityLocked(
3070                focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
3071            return;
3072        }
3073
3074        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
3075                + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
3076        mFocusedActivity = null;
3077        EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
3078    }
3079
3080    @Override
3081    public void setFocusedStack(int stackId) {
3082        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3083        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3084        final long callingId = Binder.clearCallingIdentity();
3085        try {
3086            synchronized (this) {
3087                final ActivityStack stack = mStackSupervisor.getStack(stackId);
3088                if (stack == null) {
3089                    return;
3090                }
3091                final ActivityRecord r = stack.topRunningActivityLocked();
3092                if (setFocusedActivityLocked(r, "setFocusedStack")) {
3093                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3094                }
3095            }
3096        } finally {
3097            Binder.restoreCallingIdentity(callingId);
3098        }
3099    }
3100
3101    @Override
3102    public void setFocusedTask(int taskId) {
3103        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3104        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3105        final long callingId = Binder.clearCallingIdentity();
3106        try {
3107            synchronized (this) {
3108                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3109                if (task == null) {
3110                    return;
3111                }
3112                if (mUserController.shouldConfirmCredentials(task.userId)) {
3113                    mActivityStarter.showConfirmDeviceCredential(task.userId);
3114                    if (task.stack != null && task.stack.mStackId == FREEFORM_WORKSPACE_STACK_ID) {
3115                        mStackSupervisor.moveTaskToStackLocked(task.taskId,
3116                                FULLSCREEN_WORKSPACE_STACK_ID, !ON_TOP, !FORCE_FOCUS,
3117                                "setFocusedTask", ANIMATE);
3118                    }
3119                    return;
3120                }
3121                final ActivityRecord r = task.topRunningActivityLocked();
3122                if (setFocusedActivityLocked(r, "setFocusedTask")) {
3123                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3124                }
3125            }
3126        } finally {
3127            Binder.restoreCallingIdentity(callingId);
3128        }
3129    }
3130
3131    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3132    @Override
3133    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3134        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3135        synchronized (this) {
3136            if (listener != null) {
3137                mTaskStackListeners.register(listener);
3138            }
3139        }
3140    }
3141
3142    @Override
3143    public void notifyActivityDrawn(IBinder token) {
3144        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3145        synchronized (this) {
3146            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3147            if (r != null) {
3148                r.task.stack.notifyActivityDrawnLocked(r);
3149            }
3150        }
3151    }
3152
3153    final void applyUpdateLockStateLocked(ActivityRecord r) {
3154        // Modifications to the UpdateLock state are done on our handler, outside
3155        // the activity manager's locks.  The new state is determined based on the
3156        // state *now* of the relevant activity record.  The object is passed to
3157        // the handler solely for logging detail, not to be consulted/modified.
3158        final boolean nextState = r != null && r.immersive;
3159        mHandler.sendMessage(
3160                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3161    }
3162
3163    final void applyUpdateVrModeLocked(ActivityRecord r) {
3164        mHandler.sendMessage(
3165                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3166    }
3167
3168    private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
3169        mHandler.sendMessage(
3170                mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
3171    }
3172
3173    private void applyVrMode(boolean enabled, ComponentName packageName, int userId,
3174            ComponentName callingPackage, boolean immediate) {
3175        VrManagerInternal vrService =
3176                LocalServices.getService(VrManagerInternal.class);
3177        if (immediate) {
3178            vrService.setVrModeImmediate(enabled, packageName, userId, callingPackage);
3179        } else {
3180            vrService.setVrMode(enabled, packageName, userId, callingPackage);
3181        }
3182    }
3183
3184    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3185        Message msg = Message.obtain();
3186        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3187        msg.obj = r.task.askedCompatMode ? null : r;
3188        mUiHandler.sendMessage(msg);
3189    }
3190
3191    final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3192        if (mConfiguration.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3193                && r.appInfo.requiresSmallestWidthDp > mConfiguration.smallestScreenWidthDp) {
3194            final Message msg = Message.obtain();
3195            msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3196            msg.obj = r;
3197            mUiHandler.sendMessage(msg);
3198        }
3199    }
3200
3201    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3202            String what, Object obj, ProcessRecord srcApp) {
3203        app.lastActivityTime = now;
3204
3205        if (app.activities.size() > 0) {
3206            // Don't want to touch dependent processes that are hosting activities.
3207            return index;
3208        }
3209
3210        int lrui = mLruProcesses.lastIndexOf(app);
3211        if (lrui < 0) {
3212            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3213                    + what + " " + obj + " from " + srcApp);
3214            return index;
3215        }
3216
3217        if (lrui >= index) {
3218            // Don't want to cause this to move dependent processes *back* in the
3219            // list as if they were less frequently used.
3220            return index;
3221        }
3222
3223        if (lrui >= mLruProcessActivityStart) {
3224            // Don't want to touch dependent processes that are hosting activities.
3225            return index;
3226        }
3227
3228        mLruProcesses.remove(lrui);
3229        if (index > 0) {
3230            index--;
3231        }
3232        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3233                + " in LRU list: " + app);
3234        mLruProcesses.add(index, app);
3235        return index;
3236    }
3237
3238    static void killProcessGroup(int uid, int pid) {
3239        if (sKillHandler != null) {
3240            sKillHandler.sendMessage(
3241                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3242        } else {
3243            Slog.w(TAG, "Asked to kill process group before system bringup!");
3244            Process.killProcessGroup(uid, pid);
3245        }
3246    }
3247
3248    final void removeLruProcessLocked(ProcessRecord app) {
3249        int lrui = mLruProcesses.lastIndexOf(app);
3250        if (lrui >= 0) {
3251            if (!app.killed) {
3252                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3253                Process.killProcessQuiet(app.pid);
3254                killProcessGroup(app.uid, app.pid);
3255            }
3256            if (lrui <= mLruProcessActivityStart) {
3257                mLruProcessActivityStart--;
3258            }
3259            if (lrui <= mLruProcessServiceStart) {
3260                mLruProcessServiceStart--;
3261            }
3262            mLruProcesses.remove(lrui);
3263        }
3264    }
3265
3266    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3267            ProcessRecord client) {
3268        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3269                || app.treatLikeActivity;
3270        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3271        if (!activityChange && hasActivity) {
3272            // The process has activities, so we are only allowing activity-based adjustments
3273            // to move it.  It should be kept in the front of the list with other
3274            // processes that have activities, and we don't want those to change their
3275            // order except due to activity operations.
3276            return;
3277        }
3278
3279        mLruSeq++;
3280        final long now = SystemClock.uptimeMillis();
3281        app.lastActivityTime = now;
3282
3283        // First a quick reject: if the app is already at the position we will
3284        // put it, then there is nothing to do.
3285        if (hasActivity) {
3286            final int N = mLruProcesses.size();
3287            if (N > 0 && mLruProcesses.get(N-1) == app) {
3288                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3289                return;
3290            }
3291        } else {
3292            if (mLruProcessServiceStart > 0
3293                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3294                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3295                return;
3296            }
3297        }
3298
3299        int lrui = mLruProcesses.lastIndexOf(app);
3300
3301        if (app.persistent && lrui >= 0) {
3302            // We don't care about the position of persistent processes, as long as
3303            // they are in the list.
3304            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3305            return;
3306        }
3307
3308        /* In progress: compute new position first, so we can avoid doing work
3309           if the process is not actually going to move.  Not yet working.
3310        int addIndex;
3311        int nextIndex;
3312        boolean inActivity = false, inService = false;
3313        if (hasActivity) {
3314            // Process has activities, put it at the very tipsy-top.
3315            addIndex = mLruProcesses.size();
3316            nextIndex = mLruProcessServiceStart;
3317            inActivity = true;
3318        } else if (hasService) {
3319            // Process has services, put it at the top of the service list.
3320            addIndex = mLruProcessActivityStart;
3321            nextIndex = mLruProcessServiceStart;
3322            inActivity = true;
3323            inService = true;
3324        } else  {
3325            // Process not otherwise of interest, it goes to the top of the non-service area.
3326            addIndex = mLruProcessServiceStart;
3327            if (client != null) {
3328                int clientIndex = mLruProcesses.lastIndexOf(client);
3329                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3330                        + app);
3331                if (clientIndex >= 0 && addIndex > clientIndex) {
3332                    addIndex = clientIndex;
3333                }
3334            }
3335            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3336        }
3337
3338        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3339                + mLruProcessActivityStart + "): " + app);
3340        */
3341
3342        if (lrui >= 0) {
3343            if (lrui < mLruProcessActivityStart) {
3344                mLruProcessActivityStart--;
3345            }
3346            if (lrui < mLruProcessServiceStart) {
3347                mLruProcessServiceStart--;
3348            }
3349            /*
3350            if (addIndex > lrui) {
3351                addIndex--;
3352            }
3353            if (nextIndex > lrui) {
3354                nextIndex--;
3355            }
3356            */
3357            mLruProcesses.remove(lrui);
3358        }
3359
3360        /*
3361        mLruProcesses.add(addIndex, app);
3362        if (inActivity) {
3363            mLruProcessActivityStart++;
3364        }
3365        if (inService) {
3366            mLruProcessActivityStart++;
3367        }
3368        */
3369
3370        int nextIndex;
3371        if (hasActivity) {
3372            final int N = mLruProcesses.size();
3373            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3374                // Process doesn't have activities, but has clients with
3375                // activities...  move it up, but one below the top (the top
3376                // should always have a real activity).
3377                if (DEBUG_LRU) Slog.d(TAG_LRU,
3378                        "Adding to second-top of LRU activity list: " + app);
3379                mLruProcesses.add(N - 1, app);
3380                // To keep it from spamming the LRU list (by making a bunch of clients),
3381                // we will push down any other entries owned by the app.
3382                final int uid = app.info.uid;
3383                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3384                    ProcessRecord subProc = mLruProcesses.get(i);
3385                    if (subProc.info.uid == uid) {
3386                        // We want to push this one down the list.  If the process after
3387                        // it is for the same uid, however, don't do so, because we don't
3388                        // want them internally to be re-ordered.
3389                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3390                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3391                                    "Pushing uid " + uid + " swapping at " + i + ": "
3392                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3393                            ProcessRecord tmp = mLruProcesses.get(i);
3394                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3395                            mLruProcesses.set(i - 1, tmp);
3396                            i--;
3397                        }
3398                    } else {
3399                        // A gap, we can stop here.
3400                        break;
3401                    }
3402                }
3403            } else {
3404                // Process has activities, put it at the very tipsy-top.
3405                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3406                mLruProcesses.add(app);
3407            }
3408            nextIndex = mLruProcessServiceStart;
3409        } else if (hasService) {
3410            // Process has services, put it at the top of the service list.
3411            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3412            mLruProcesses.add(mLruProcessActivityStart, app);
3413            nextIndex = mLruProcessServiceStart;
3414            mLruProcessActivityStart++;
3415        } else  {
3416            // Process not otherwise of interest, it goes to the top of the non-service area.
3417            int index = mLruProcessServiceStart;
3418            if (client != null) {
3419                // If there is a client, don't allow the process to be moved up higher
3420                // in the list than that client.
3421                int clientIndex = mLruProcesses.lastIndexOf(client);
3422                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3423                        + " when updating " + app);
3424                if (clientIndex <= lrui) {
3425                    // Don't allow the client index restriction to push it down farther in the
3426                    // list than it already is.
3427                    clientIndex = lrui;
3428                }
3429                if (clientIndex >= 0 && index > clientIndex) {
3430                    index = clientIndex;
3431                }
3432            }
3433            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3434            mLruProcesses.add(index, app);
3435            nextIndex = index-1;
3436            mLruProcessActivityStart++;
3437            mLruProcessServiceStart++;
3438        }
3439
3440        // If the app is currently using a content provider or service,
3441        // bump those processes as well.
3442        for (int j=app.connections.size()-1; j>=0; j--) {
3443            ConnectionRecord cr = app.connections.valueAt(j);
3444            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3445                    && cr.binding.service.app != null
3446                    && cr.binding.service.app.lruSeq != mLruSeq
3447                    && !cr.binding.service.app.persistent) {
3448                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3449                        "service connection", cr, app);
3450            }
3451        }
3452        for (int j=app.conProviders.size()-1; j>=0; j--) {
3453            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3454            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3455                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3456                        "provider reference", cpr, app);
3457            }
3458        }
3459    }
3460
3461    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3462        if (uid == Process.SYSTEM_UID) {
3463            // The system gets to run in any process.  If there are multiple
3464            // processes with the same uid, just pick the first (this
3465            // should never happen).
3466            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3467            if (procs == null) return null;
3468            final int procCount = procs.size();
3469            for (int i = 0; i < procCount; i++) {
3470                final int procUid = procs.keyAt(i);
3471                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3472                    // Don't use an app process or different user process for system component.
3473                    continue;
3474                }
3475                return procs.valueAt(i);
3476            }
3477        }
3478        ProcessRecord proc = mProcessNames.get(processName, uid);
3479        if (false && proc != null && !keepIfLarge
3480                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3481                && proc.lastCachedPss >= 4000) {
3482            // Turn this condition on to cause killing to happen regularly, for testing.
3483            if (proc.baseProcessTracker != null) {
3484                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3485            }
3486            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3487        } else if (proc != null && !keepIfLarge
3488                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3489                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3490            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3491            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3492                if (proc.baseProcessTracker != null) {
3493                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3494                }
3495                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3496            }
3497        }
3498        return proc;
3499    }
3500
3501    void notifyPackageUse(String packageName, int reason) {
3502        IPackageManager pm = AppGlobals.getPackageManager();
3503        try {
3504            pm.notifyPackageUse(packageName, reason);
3505        } catch (RemoteException e) {
3506        }
3507    }
3508
3509    boolean isNextTransitionForward() {
3510        int transit = mWindowManager.getPendingAppTransition();
3511        return transit == TRANSIT_ACTIVITY_OPEN
3512                || transit == TRANSIT_TASK_OPEN
3513                || transit == TRANSIT_TASK_TO_FRONT;
3514    }
3515
3516    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3517            String processName, String abiOverride, int uid, Runnable crashHandler) {
3518        synchronized(this) {
3519            ApplicationInfo info = new ApplicationInfo();
3520            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3521            // For isolated processes, the former contains the parent's uid and the latter the
3522            // actual uid of the isolated process.
3523            // In the special case introduced by this method (which is, starting an isolated
3524            // process directly from the SystemServer without an actual parent app process) the
3525            // closest thing to a parent's uid is SYSTEM_UID.
3526            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3527            // the |isolated| logic in the ProcessRecord constructor.
3528            info.uid = Process.SYSTEM_UID;
3529            info.processName = processName;
3530            info.className = entryPoint;
3531            info.packageName = "android";
3532            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3533                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3534                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3535                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3536                    crashHandler);
3537            return proc != null ? proc.pid : 0;
3538        }
3539    }
3540
3541    final ProcessRecord startProcessLocked(String processName,
3542            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3543            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3544            boolean isolated, boolean keepIfLarge) {
3545        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3546                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3547                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3548                null /* crashHandler */);
3549    }
3550
3551    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3552            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3553            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3554            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3555        long startTime = SystemClock.elapsedRealtime();
3556        ProcessRecord app;
3557        if (!isolated) {
3558            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3559            checkTime(startTime, "startProcess: after getProcessRecord");
3560
3561            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3562                // If we are in the background, then check to see if this process
3563                // is bad.  If so, we will just silently fail.
3564                if (mAppErrors.isBadProcessLocked(info)) {
3565                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3566                            + "/" + info.processName);
3567                    return null;
3568                }
3569            } else {
3570                // When the user is explicitly starting a process, then clear its
3571                // crash count so that we won't make it bad until they see at
3572                // least one crash dialog again, and make the process good again
3573                // if it had been bad.
3574                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3575                        + "/" + info.processName);
3576                mAppErrors.resetProcessCrashTimeLocked(info);
3577                if (mAppErrors.isBadProcessLocked(info)) {
3578                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3579                            UserHandle.getUserId(info.uid), info.uid,
3580                            info.processName);
3581                    mAppErrors.clearBadProcessLocked(info);
3582                    if (app != null) {
3583                        app.bad = false;
3584                    }
3585                }
3586            }
3587        } else {
3588            // If this is an isolated process, it can't re-use an existing process.
3589            app = null;
3590        }
3591
3592        // app launch boost for big.little configurations
3593        // use cpusets to migrate freshly launched tasks to big cores
3594        nativeMigrateToBoost();
3595        mIsBoosted = true;
3596        mBoostStartTime = SystemClock.uptimeMillis();
3597        Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3598        mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3599
3600        // We don't have to do anything more if:
3601        // (1) There is an existing application record; and
3602        // (2) The caller doesn't think it is dead, OR there is no thread
3603        //     object attached to it so we know it couldn't have crashed; and
3604        // (3) There is a pid assigned to it, so it is either starting or
3605        //     already running.
3606        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3607                + " app=" + app + " knownToBeDead=" + knownToBeDead
3608                + " thread=" + (app != null ? app.thread : null)
3609                + " pid=" + (app != null ? app.pid : -1));
3610        if (app != null && app.pid > 0) {
3611            if ((!knownToBeDead && !app.killed) || app.thread == null) {
3612                // We already have the app running, or are waiting for it to
3613                // come up (we have a pid but not yet its thread), so keep it.
3614                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3615                // If this is a new package in the process, add the package to the list
3616                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3617                checkTime(startTime, "startProcess: done, added package to proc");
3618                return app;
3619            }
3620
3621            // An application record is attached to a previous process,
3622            // clean it up now.
3623            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3624            checkTime(startTime, "startProcess: bad proc running, killing");
3625            killProcessGroup(app.uid, app.pid);
3626            handleAppDiedLocked(app, true, true);
3627            checkTime(startTime, "startProcess: done killing old proc");
3628        }
3629
3630        String hostingNameStr = hostingName != null
3631                ? hostingName.flattenToShortString() : null;
3632
3633        if (app == null) {
3634            checkTime(startTime, "startProcess: creating new process record");
3635            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3636            if (app == null) {
3637                Slog.w(TAG, "Failed making new process record for "
3638                        + processName + "/" + info.uid + " isolated=" + isolated);
3639                return null;
3640            }
3641            app.crashHandler = crashHandler;
3642            checkTime(startTime, "startProcess: done creating new process record");
3643        } else {
3644            // If this is a new package in the process, add the package to the list
3645            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3646            checkTime(startTime, "startProcess: added package to existing proc");
3647        }
3648
3649        // If the system is not ready yet, then hold off on starting this
3650        // process until it is.
3651        if (!mProcessesReady
3652                && !isAllowedWhileBooting(info)
3653                && !allowWhileBooting) {
3654            if (!mProcessesOnHold.contains(app)) {
3655                mProcessesOnHold.add(app);
3656            }
3657            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3658                    "System not ready, putting on hold: " + app);
3659            checkTime(startTime, "startProcess: returning with proc on hold");
3660            return app;
3661        }
3662
3663        checkTime(startTime, "startProcess: stepping in to startProcess");
3664        startProcessLocked(
3665                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3666        checkTime(startTime, "startProcess: done starting proc!");
3667        return (app.pid != 0) ? app : null;
3668    }
3669
3670    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3671        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3672    }
3673
3674    private final void startProcessLocked(ProcessRecord app,
3675            String hostingType, String hostingNameStr) {
3676        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3677                null /* entryPoint */, null /* entryPointArgs */);
3678    }
3679
3680    private final void startProcessLocked(ProcessRecord app, String hostingType,
3681            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3682        long startTime = SystemClock.elapsedRealtime();
3683        if (app.pid > 0 && app.pid != MY_PID) {
3684            checkTime(startTime, "startProcess: removing from pids map");
3685            synchronized (mPidsSelfLocked) {
3686                mPidsSelfLocked.remove(app.pid);
3687                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3688            }
3689            checkTime(startTime, "startProcess: done removing from pids map");
3690            app.setPid(0);
3691        }
3692
3693        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3694                "startProcessLocked removing on hold: " + app);
3695        mProcessesOnHold.remove(app);
3696
3697        checkTime(startTime, "startProcess: starting to update cpu stats");
3698        updateCpuStats();
3699        checkTime(startTime, "startProcess: done updating cpu stats");
3700
3701        try {
3702            try {
3703                final int userId = UserHandle.getUserId(app.uid);
3704                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3705            } catch (RemoteException e) {
3706                throw e.rethrowAsRuntimeException();
3707            }
3708
3709            int uid = app.uid;
3710            int[] gids = null;
3711            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3712            if (!app.isolated) {
3713                int[] permGids = null;
3714                try {
3715                    checkTime(startTime, "startProcess: getting gids from package manager");
3716                    final IPackageManager pm = AppGlobals.getPackageManager();
3717                    permGids = pm.getPackageGids(app.info.packageName,
3718                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3719                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3720                            MountServiceInternal.class);
3721                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3722                            app.info.packageName);
3723                } catch (RemoteException e) {
3724                    throw e.rethrowAsRuntimeException();
3725                }
3726
3727                /*
3728                 * Add shared application and profile GIDs so applications can share some
3729                 * resources like shared libraries and access user-wide resources
3730                 */
3731                if (ArrayUtils.isEmpty(permGids)) {
3732                    gids = new int[3];
3733                } else {
3734                    gids = new int[permGids.length + 3];
3735                    System.arraycopy(permGids, 0, gids, 3, permGids.length);
3736                }
3737                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3738                gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
3739                gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3740            }
3741            checkTime(startTime, "startProcess: building args");
3742            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3743                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3744                        && mTopComponent != null
3745                        && app.processName.equals(mTopComponent.getPackageName())) {
3746                    uid = 0;
3747                }
3748                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3749                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3750                    uid = 0;
3751                }
3752            }
3753            int debugFlags = 0;
3754            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3755                debugFlags |= Zygote.DEBUG_ENABLE_JDWP;
3756                debugFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE;
3757                // Also turn on CheckJNI for debuggable apps. It's quite
3758                // awkward to turn on otherwise.
3759                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3760            }
3761            // Run the app in safe mode if its manifest requests so or the
3762            // system is booted in safe mode.
3763            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3764                mSafeMode == true) {
3765                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3766            }
3767            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3768                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3769            }
3770            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3771            if ("true".equals(genDebugInfoProperty)) {
3772                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3773            }
3774            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3775                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3776            }
3777            if ("1".equals(SystemProperties.get("debug.assert"))) {
3778                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3779            }
3780            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3781                // Enable all debug flags required by the native debugger.
3782                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3783                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3784                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3785                mNativeDebuggingApp = null;
3786            }
3787
3788            String invokeWith = null;
3789            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3790                // Debuggable apps may include a wrapper script with their library directory.
3791                String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
3792                if (new File(wrapperFileName).exists()) {
3793                    invokeWith = "/system/bin/logwrapper " + wrapperFileName;
3794                }
3795            }
3796
3797            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3798            if (requiredAbi == null) {
3799                requiredAbi = Build.SUPPORTED_ABIS[0];
3800            }
3801
3802            String instructionSet = null;
3803            if (app.info.primaryCpuAbi != null) {
3804                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3805            }
3806
3807            app.gids = gids;
3808            app.requiredAbi = requiredAbi;
3809            app.instructionSet = instructionSet;
3810
3811            // Start the process.  It will either succeed and return a result containing
3812            // the PID of the new process, or else throw a RuntimeException.
3813            boolean isActivityProcess = (entryPoint == null);
3814            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3815            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3816                    app.processName);
3817            checkTime(startTime, "startProcess: asking zygote to start proc");
3818            Process.ProcessStartResult startResult;
3819            if (hostingType.equals("webview_service")) {
3820                startResult = Process.startWebView(entryPoint,
3821                        app.processName, uid, uid, gids, debugFlags, mountExternal,
3822                        app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3823                        app.info.dataDir, null, entryPointArgs);
3824            } else {
3825                startResult = Process.start(entryPoint,
3826                        app.processName, uid, uid, gids, debugFlags, mountExternal,
3827                        app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3828                        app.info.dataDir, invokeWith, entryPointArgs);
3829            }
3830            checkTime(startTime, "startProcess: returned from zygote!");
3831            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3832
3833            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3834            checkTime(startTime, "startProcess: done updating battery stats");
3835
3836            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3837                    UserHandle.getUserId(uid), startResult.pid, uid,
3838                    app.processName, hostingType,
3839                    hostingNameStr != null ? hostingNameStr : "");
3840
3841            try {
3842                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3843                        app.info.seinfo, app.info.sourceDir, startResult.pid);
3844            } catch (RemoteException ex) {
3845                // Ignore
3846            }
3847
3848            if (app.persistent) {
3849                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3850            }
3851
3852            checkTime(startTime, "startProcess: building log message");
3853            StringBuilder buf = mStringBuilder;
3854            buf.setLength(0);
3855            buf.append("Start proc ");
3856            buf.append(startResult.pid);
3857            buf.append(':');
3858            buf.append(app.processName);
3859            buf.append('/');
3860            UserHandle.formatUid(buf, uid);
3861            if (!isActivityProcess) {
3862                buf.append(" [");
3863                buf.append(entryPoint);
3864                buf.append("]");
3865            }
3866            buf.append(" for ");
3867            buf.append(hostingType);
3868            if (hostingNameStr != null) {
3869                buf.append(" ");
3870                buf.append(hostingNameStr);
3871            }
3872            Slog.i(TAG, buf.toString());
3873            app.setPid(startResult.pid);
3874            app.usingWrapper = startResult.usingWrapper;
3875            app.removed = false;
3876            app.killed = false;
3877            app.killedByAm = false;
3878            checkTime(startTime, "startProcess: starting to update pids map");
3879            ProcessRecord oldApp;
3880            synchronized (mPidsSelfLocked) {
3881                oldApp = mPidsSelfLocked.get(startResult.pid);
3882            }
3883            // If there is already an app occupying that pid that hasn't been cleaned up
3884            if (oldApp != null && !app.isolated) {
3885                // Clean up anything relating to this pid first
3886                Slog.w(TAG, "Reusing pid " + startResult.pid
3887                        + " while app is still mapped to it");
3888                cleanUpApplicationRecordLocked(oldApp, false, false, -1,
3889                        true /*replacingPid*/);
3890            }
3891            synchronized (mPidsSelfLocked) {
3892                this.mPidsSelfLocked.put(startResult.pid, app);
3893                if (isActivityProcess) {
3894                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3895                    msg.obj = app;
3896                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3897                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3898                }
3899            }
3900            checkTime(startTime, "startProcess: done updating pids map");
3901        } catch (RuntimeException e) {
3902            Slog.e(TAG, "Failure starting process " + app.processName, e);
3903
3904            // Something went very wrong while trying to start this process; one
3905            // common case is when the package is frozen due to an active
3906            // upgrade. To recover, clean up any active bookkeeping related to
3907            // starting this process. (We already invoked this method once when
3908            // the package was initially frozen through KILL_APPLICATION_MSG, so
3909            // it doesn't hurt to use it again.)
3910            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3911                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3912        }
3913    }
3914
3915    void updateUsageStats(ActivityRecord component, boolean resumed) {
3916        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3917                "updateUsageStats: comp=" + component + "res=" + resumed);
3918        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3919        if (resumed) {
3920            if (mUsageStatsService != null) {
3921                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3922                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3923            }
3924            synchronized (stats) {
3925                stats.noteActivityResumedLocked(component.app.uid);
3926            }
3927        } else {
3928            if (mUsageStatsService != null) {
3929                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3930                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3931            }
3932            synchronized (stats) {
3933                stats.noteActivityPausedLocked(component.app.uid);
3934            }
3935        }
3936    }
3937
3938    Intent getHomeIntent() {
3939        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3940        intent.setComponent(mTopComponent);
3941        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3942        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3943            intent.addCategory(Intent.CATEGORY_HOME);
3944        }
3945        return intent;
3946    }
3947
3948    boolean startHomeActivityLocked(int userId, String reason) {
3949        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3950                && mTopAction == null) {
3951            // We are running in factory test mode, but unable to find
3952            // the factory test app, so just sit around displaying the
3953            // error message and don't try to start anything.
3954            return false;
3955        }
3956        Intent intent = getHomeIntent();
3957        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3958        if (aInfo != null) {
3959            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3960            // Don't do this if the home app is currently being
3961            // instrumented.
3962            aInfo = new ActivityInfo(aInfo);
3963            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3964            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3965                    aInfo.applicationInfo.uid, true);
3966            if (app == null || app.instrumentationClass == null) {
3967                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3968                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3969            }
3970        } else {
3971            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3972        }
3973
3974        return true;
3975    }
3976
3977    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3978        ActivityInfo ai = null;
3979        ComponentName comp = intent.getComponent();
3980        try {
3981            if (comp != null) {
3982                // Factory test.
3983                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3984            } else {
3985                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3986                        intent,
3987                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3988                        flags, userId);
3989
3990                if (info != null) {
3991                    ai = info.activityInfo;
3992                }
3993            }
3994        } catch (RemoteException e) {
3995            // ignore
3996        }
3997
3998        return ai;
3999    }
4000
4001    /**
4002     * Starts the "new version setup screen" if appropriate.
4003     */
4004    void startSetupActivityLocked() {
4005        // Only do this once per boot.
4006        if (mCheckedForSetup) {
4007            return;
4008        }
4009
4010        // We will show this screen if the current one is a different
4011        // version than the last one shown, and we are not running in
4012        // low-level factory test mode.
4013        final ContentResolver resolver = mContext.getContentResolver();
4014        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
4015                Settings.Global.getInt(resolver,
4016                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
4017            mCheckedForSetup = true;
4018
4019            // See if we should be showing the platform update setup UI.
4020            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
4021            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
4022                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
4023            if (!ris.isEmpty()) {
4024                final ResolveInfo ri = ris.get(0);
4025                String vers = ri.activityInfo.metaData != null
4026                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
4027                        : null;
4028                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
4029                    vers = ri.activityInfo.applicationInfo.metaData.getString(
4030                            Intent.METADATA_SETUP_VERSION);
4031                }
4032                String lastVers = Settings.Secure.getString(
4033                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
4034                if (vers != null && !vers.equals(lastVers)) {
4035                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
4036                    intent.setComponent(new ComponentName(
4037                            ri.activityInfo.packageName, ri.activityInfo.name));
4038                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
4039                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
4040                            null, 0, 0, 0, null, false, false, null, null, null);
4041                }
4042            }
4043        }
4044    }
4045
4046    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
4047        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
4048    }
4049
4050    void enforceNotIsolatedCaller(String caller) {
4051        if (UserHandle.isIsolated(Binder.getCallingUid())) {
4052            throw new SecurityException("Isolated process not allowed to call " + caller);
4053        }
4054    }
4055
4056    void enforceShellRestriction(String restriction, int userHandle) {
4057        if (Binder.getCallingUid() == Process.SHELL_UID) {
4058            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
4059                throw new SecurityException("Shell does not have permission to access user "
4060                        + userHandle);
4061            }
4062        }
4063    }
4064
4065    @Override
4066    public int getFrontActivityScreenCompatMode() {
4067        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4068        synchronized (this) {
4069            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4070        }
4071    }
4072
4073    @Override
4074    public void setFrontActivityScreenCompatMode(int mode) {
4075        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4076                "setFrontActivityScreenCompatMode");
4077        synchronized (this) {
4078            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4079        }
4080    }
4081
4082    @Override
4083    public int getPackageScreenCompatMode(String packageName) {
4084        enforceNotIsolatedCaller("getPackageScreenCompatMode");
4085        synchronized (this) {
4086            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4087        }
4088    }
4089
4090    @Override
4091    public void setPackageScreenCompatMode(String packageName, int mode) {
4092        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4093                "setPackageScreenCompatMode");
4094        synchronized (this) {
4095            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4096        }
4097    }
4098
4099    @Override
4100    public boolean getPackageAskScreenCompat(String packageName) {
4101        enforceNotIsolatedCaller("getPackageAskScreenCompat");
4102        synchronized (this) {
4103            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4104        }
4105    }
4106
4107    @Override
4108    public void setPackageAskScreenCompat(String packageName, boolean ask) {
4109        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4110                "setPackageAskScreenCompat");
4111        synchronized (this) {
4112            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4113        }
4114    }
4115
4116    private boolean hasUsageStatsPermission(String callingPackage) {
4117        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4118                Binder.getCallingUid(), callingPackage);
4119        if (mode == AppOpsManager.MODE_DEFAULT) {
4120            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4121                    == PackageManager.PERMISSION_GRANTED;
4122        }
4123        return mode == AppOpsManager.MODE_ALLOWED;
4124    }
4125
4126    @Override
4127    public int getPackageProcessState(String packageName, String callingPackage) {
4128        if (!hasUsageStatsPermission(callingPackage)) {
4129            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
4130                    "getPackageProcessState");
4131        }
4132
4133        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4134        synchronized (this) {
4135            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4136                final ProcessRecord proc = mLruProcesses.get(i);
4137                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
4138                        || procState > proc.setProcState) {
4139                    boolean found = false;
4140                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
4141                        if (proc.pkgList.keyAt(j).equals(packageName)) {
4142                            procState = proc.setProcState;
4143                            found = true;
4144                        }
4145                    }
4146                    if (proc.pkgDeps != null && !found) {
4147                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
4148                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
4149                                procState = proc.setProcState;
4150                                break;
4151                            }
4152                        }
4153                    }
4154                }
4155            }
4156        }
4157        return procState;
4158    }
4159
4160    @Override
4161    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
4162        synchronized (this) {
4163            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4164            if (app == null) {
4165                return false;
4166            }
4167            if (app.trimMemoryLevel < level && app.thread != null &&
4168                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4169                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4170                try {
4171                    app.thread.scheduleTrimMemory(level);
4172                    app.trimMemoryLevel = level;
4173                    return true;
4174                } catch (RemoteException e) {
4175                    // Fallthrough to failure case.
4176                }
4177            }
4178        }
4179        return false;
4180    }
4181
4182    private void dispatchProcessesChanged() {
4183        int N;
4184        synchronized (this) {
4185            N = mPendingProcessChanges.size();
4186            if (mActiveProcessChanges.length < N) {
4187                mActiveProcessChanges = new ProcessChangeItem[N];
4188            }
4189            mPendingProcessChanges.toArray(mActiveProcessChanges);
4190            mPendingProcessChanges.clear();
4191            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4192                    "*** Delivering " + N + " process changes");
4193        }
4194
4195        int i = mProcessObservers.beginBroadcast();
4196        while (i > 0) {
4197            i--;
4198            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4199            if (observer != null) {
4200                try {
4201                    for (int j=0; j<N; j++) {
4202                        ProcessChangeItem item = mActiveProcessChanges[j];
4203                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4204                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4205                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4206                                    + item.uid + ": " + item.foregroundActivities);
4207                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4208                                    item.foregroundActivities);
4209                        }
4210                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4211                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4212                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4213                                    + ": " + item.processState);
4214                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4215                        }
4216                    }
4217                } catch (RemoteException e) {
4218                }
4219            }
4220        }
4221        mProcessObservers.finishBroadcast();
4222
4223        synchronized (this) {
4224            for (int j=0; j<N; j++) {
4225                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4226            }
4227        }
4228    }
4229
4230    private void dispatchProcessDied(int pid, int uid) {
4231        int i = mProcessObservers.beginBroadcast();
4232        while (i > 0) {
4233            i--;
4234            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4235            if (observer != null) {
4236                try {
4237                    observer.onProcessDied(pid, uid);
4238                } catch (RemoteException e) {
4239                }
4240            }
4241        }
4242        mProcessObservers.finishBroadcast();
4243    }
4244
4245    private void dispatchUidsChanged() {
4246        int N;
4247        synchronized (this) {
4248            N = mPendingUidChanges.size();
4249            if (mActiveUidChanges.length < N) {
4250                mActiveUidChanges = new UidRecord.ChangeItem[N];
4251            }
4252            for (int i=0; i<N; i++) {
4253                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4254                mActiveUidChanges[i] = change;
4255                if (change.uidRecord != null) {
4256                    change.uidRecord.pendingChange = null;
4257                    change.uidRecord = null;
4258                }
4259            }
4260            mPendingUidChanges.clear();
4261            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4262                    "*** Delivering " + N + " uid changes");
4263        }
4264
4265        if (mLocalPowerManager != null) {
4266            for (int j=0; j<N; j++) {
4267                UidRecord.ChangeItem item = mActiveUidChanges[j];
4268                if (item.change == UidRecord.CHANGE_GONE
4269                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
4270                    mLocalPowerManager.uidGone(item.uid);
4271                } else {
4272                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4273                }
4274            }
4275        }
4276
4277        int i = mUidObservers.beginBroadcast();
4278        while (i > 0) {
4279            i--;
4280            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4281            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4282            if (observer != null) {
4283                try {
4284                    for (int j=0; j<N; j++) {
4285                        UidRecord.ChangeItem item = mActiveUidChanges[j];
4286                        final int change = item.change;
4287                        UidRecord validateUid = null;
4288                        if (VALIDATE_UID_STATES && i == 0) {
4289                            validateUid = mValidateUids.get(item.uid);
4290                            if (validateUid == null && change != UidRecord.CHANGE_GONE
4291                                    && change != UidRecord.CHANGE_GONE_IDLE) {
4292                                validateUid = new UidRecord(item.uid);
4293                                mValidateUids.put(item.uid, validateUid);
4294                            }
4295                        }
4296                        if (change == UidRecord.CHANGE_IDLE
4297                                || change == UidRecord.CHANGE_GONE_IDLE) {
4298                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4299                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4300                                        "UID idle uid=" + item.uid);
4301                                observer.onUidIdle(item.uid);
4302                            }
4303                            if (VALIDATE_UID_STATES && i == 0) {
4304                                if (validateUid != null) {
4305                                    validateUid.idle = true;
4306                                }
4307                            }
4308                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4309                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4310                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4311                                        "UID active uid=" + item.uid);
4312                                observer.onUidActive(item.uid);
4313                            }
4314                            if (VALIDATE_UID_STATES && i == 0) {
4315                                validateUid.idle = false;
4316                            }
4317                        }
4318                        if (change == UidRecord.CHANGE_GONE
4319                                || change == UidRecord.CHANGE_GONE_IDLE) {
4320                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4321                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4322                                        "UID gone uid=" + item.uid);
4323                                observer.onUidGone(item.uid);
4324                            }
4325                            if (VALIDATE_UID_STATES && i == 0) {
4326                                if (validateUid != null) {
4327                                    mValidateUids.remove(item.uid);
4328                                }
4329                            }
4330                        } else {
4331                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4332                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4333                                        "UID CHANGED uid=" + item.uid
4334                                                + ": " + item.processState);
4335                                observer.onUidStateChanged(item.uid, item.processState);
4336                            }
4337                            if (VALIDATE_UID_STATES && i == 0) {
4338                                validateUid.curProcState = validateUid.setProcState
4339                                        = item.processState;
4340                            }
4341                        }
4342                    }
4343                } catch (RemoteException e) {
4344                }
4345            }
4346        }
4347        mUidObservers.finishBroadcast();
4348
4349        synchronized (this) {
4350            for (int j=0; j<N; j++) {
4351                mAvailUidChanges.add(mActiveUidChanges[j]);
4352            }
4353        }
4354    }
4355
4356    @Override
4357    public final int startActivity(IApplicationThread caller, String callingPackage,
4358            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4359            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4360        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4361                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4362                UserHandle.getCallingUserId());
4363    }
4364
4365    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4366        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4367        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4368                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4369                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4370
4371        // TODO: Switch to user app stacks here.
4372        String mimeType = intent.getType();
4373        final Uri data = intent.getData();
4374        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4375            mimeType = getProviderMimeType(data, userId);
4376        }
4377        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4378
4379        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4380        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4381                null, 0, 0, null, null, null, null, false, userId, container, null);
4382    }
4383
4384    @Override
4385    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4386            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4387            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4388        enforceNotIsolatedCaller("startActivity");
4389        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4390                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4391        // TODO: Switch to user app stacks here.
4392        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4393                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4394                profilerInfo, null, null, bOptions, false, userId, null, null);
4395    }
4396
4397    @Override
4398    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4399            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4400            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4401            int userId) {
4402
4403        // This is very dangerous -- it allows you to perform a start activity (including
4404        // permission grants) as any app that may launch one of your own activities.  So
4405        // we will only allow this to be done from activities that are part of the core framework,
4406        // and then only when they are running as the system.
4407        final ActivityRecord sourceRecord;
4408        final int targetUid;
4409        final String targetPackage;
4410        synchronized (this) {
4411            if (resultTo == null) {
4412                throw new SecurityException("Must be called from an activity");
4413            }
4414            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4415            if (sourceRecord == null) {
4416                throw new SecurityException("Called with bad activity token: " + resultTo);
4417            }
4418            if (!sourceRecord.info.packageName.equals("android")) {
4419                throw new SecurityException(
4420                        "Must be called from an activity that is declared in the android package");
4421            }
4422            if (sourceRecord.app == null) {
4423                throw new SecurityException("Called without a process attached to activity");
4424            }
4425            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4426                // This is still okay, as long as this activity is running under the
4427                // uid of the original calling activity.
4428                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4429                    throw new SecurityException(
4430                            "Calling activity in uid " + sourceRecord.app.uid
4431                                    + " must be system uid or original calling uid "
4432                                    + sourceRecord.launchedFromUid);
4433                }
4434            }
4435            if (ignoreTargetSecurity) {
4436                if (intent.getComponent() == null) {
4437                    throw new SecurityException(
4438                            "Component must be specified with ignoreTargetSecurity");
4439                }
4440                if (intent.getSelector() != null) {
4441                    throw new SecurityException(
4442                            "Selector not allowed with ignoreTargetSecurity");
4443                }
4444            }
4445            targetUid = sourceRecord.launchedFromUid;
4446            targetPackage = sourceRecord.launchedFromPackage;
4447        }
4448
4449        if (userId == UserHandle.USER_NULL) {
4450            userId = UserHandle.getUserId(sourceRecord.app.uid);
4451        }
4452
4453        // TODO: Switch to user app stacks here.
4454        try {
4455            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4456                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4457                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4458            return ret;
4459        } catch (SecurityException e) {
4460            // XXX need to figure out how to propagate to original app.
4461            // A SecurityException here is generally actually a fault of the original
4462            // calling activity (such as a fairly granting permissions), so propagate it
4463            // back to them.
4464            /*
4465            StringBuilder msg = new StringBuilder();
4466            msg.append("While launching");
4467            msg.append(intent.toString());
4468            msg.append(": ");
4469            msg.append(e.getMessage());
4470            */
4471            throw e;
4472        }
4473    }
4474
4475    @Override
4476    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4477            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4478            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4479        enforceNotIsolatedCaller("startActivityAndWait");
4480        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4481                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4482        WaitResult res = new WaitResult();
4483        // TODO: Switch to user app stacks here.
4484        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4485                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4486                bOptions, false, userId, null, null);
4487        return res;
4488    }
4489
4490    @Override
4491    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4492            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4493            int startFlags, Configuration config, Bundle bOptions, int userId) {
4494        enforceNotIsolatedCaller("startActivityWithConfig");
4495        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4496                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4497        // TODO: Switch to user app stacks here.
4498        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4499                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4500                null, null, config, bOptions, false, userId, null, null);
4501        return ret;
4502    }
4503
4504    @Override
4505    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4506            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4507            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4508            throws TransactionTooLargeException {
4509        enforceNotIsolatedCaller("startActivityIntentSender");
4510        // Refuse possible leaked file descriptors
4511        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4512            throw new IllegalArgumentException("File descriptors passed in Intent");
4513        }
4514
4515        IIntentSender sender = intent.getTarget();
4516        if (!(sender instanceof PendingIntentRecord)) {
4517            throw new IllegalArgumentException("Bad PendingIntent object");
4518        }
4519
4520        PendingIntentRecord pir = (PendingIntentRecord)sender;
4521
4522        synchronized (this) {
4523            // If this is coming from the currently resumed activity, it is
4524            // effectively saying that app switches are allowed at this point.
4525            final ActivityStack stack = getFocusedStack();
4526            if (stack.mResumedActivity != null &&
4527                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4528                mAppSwitchesAllowedTime = 0;
4529            }
4530        }
4531        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4532                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4533        return ret;
4534    }
4535
4536    @Override
4537    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4538            Intent intent, String resolvedType, IVoiceInteractionSession session,
4539            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4540            Bundle bOptions, int userId) {
4541        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4542                != PackageManager.PERMISSION_GRANTED) {
4543            String msg = "Permission Denial: startVoiceActivity() from pid="
4544                    + Binder.getCallingPid()
4545                    + ", uid=" + Binder.getCallingUid()
4546                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4547            Slog.w(TAG, msg);
4548            throw new SecurityException(msg);
4549        }
4550        if (session == null || interactor == null) {
4551            throw new NullPointerException("null session or interactor");
4552        }
4553        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4554                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4555        // TODO: Switch to user app stacks here.
4556        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4557                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4558                null, bOptions, false, userId, null, null);
4559    }
4560
4561    @Override
4562    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4563            throws RemoteException {
4564        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4565        synchronized (this) {
4566            ActivityRecord activity = getFocusedStack().topActivity();
4567            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4568                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4569            }
4570            if (mRunningVoice != null || activity.task.voiceSession != null
4571                    || activity.voiceSession != null) {
4572                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4573                return;
4574            }
4575            if (activity.pendingVoiceInteractionStart) {
4576                Slog.w(TAG, "Pending start of voice interaction already.");
4577                return;
4578            }
4579            activity.pendingVoiceInteractionStart = true;
4580        }
4581        LocalServices.getService(VoiceInteractionManagerInternal.class)
4582                .startLocalVoiceInteraction(callingActivity, options);
4583    }
4584
4585    @Override
4586    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4587        LocalServices.getService(VoiceInteractionManagerInternal.class)
4588                .stopLocalVoiceInteraction(callingActivity);
4589    }
4590
4591    @Override
4592    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4593        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4594                .supportsLocalVoiceInteraction();
4595    }
4596
4597    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4598            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4599        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4600        if (activityToCallback == null) return;
4601        activityToCallback.setVoiceSessionLocked(voiceSession);
4602
4603        // Inform the activity
4604        try {
4605            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4606                    voiceInteractor);
4607            long token = Binder.clearCallingIdentity();
4608            try {
4609                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4610            } finally {
4611                Binder.restoreCallingIdentity(token);
4612            }
4613            // TODO: VI Should we cache the activity so that it's easier to find later
4614            // rather than scan through all the stacks and activities?
4615        } catch (RemoteException re) {
4616            activityToCallback.clearVoiceSessionLocked();
4617            // TODO: VI Should this terminate the voice session?
4618        }
4619    }
4620
4621    @Override
4622    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4623        synchronized (this) {
4624            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4625                if (keepAwake) {
4626                    mVoiceWakeLock.acquire();
4627                } else {
4628                    mVoiceWakeLock.release();
4629                }
4630            }
4631        }
4632    }
4633
4634    @Override
4635    public boolean startNextMatchingActivity(IBinder callingActivity,
4636            Intent intent, Bundle bOptions) {
4637        // Refuse possible leaked file descriptors
4638        if (intent != null && intent.hasFileDescriptors() == true) {
4639            throw new IllegalArgumentException("File descriptors passed in Intent");
4640        }
4641        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4642
4643        synchronized (this) {
4644            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4645            if (r == null) {
4646                ActivityOptions.abort(options);
4647                return false;
4648            }
4649            if (r.app == null || r.app.thread == null) {
4650                // The caller is not running...  d'oh!
4651                ActivityOptions.abort(options);
4652                return false;
4653            }
4654            intent = new Intent(intent);
4655            // The caller is not allowed to change the data.
4656            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4657            // And we are resetting to find the next component...
4658            intent.setComponent(null);
4659
4660            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4661
4662            ActivityInfo aInfo = null;
4663            try {
4664                List<ResolveInfo> resolves =
4665                    AppGlobals.getPackageManager().queryIntentActivities(
4666                            intent, r.resolvedType,
4667                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4668                            UserHandle.getCallingUserId()).getList();
4669
4670                // Look for the original activity in the list...
4671                final int N = resolves != null ? resolves.size() : 0;
4672                for (int i=0; i<N; i++) {
4673                    ResolveInfo rInfo = resolves.get(i);
4674                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4675                            && rInfo.activityInfo.name.equals(r.info.name)) {
4676                        // We found the current one...  the next matching is
4677                        // after it.
4678                        i++;
4679                        if (i<N) {
4680                            aInfo = resolves.get(i).activityInfo;
4681                        }
4682                        if (debug) {
4683                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4684                                    + "/" + r.info.name);
4685                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4686                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4687                        }
4688                        break;
4689                    }
4690                }
4691            } catch (RemoteException e) {
4692            }
4693
4694            if (aInfo == null) {
4695                // Nobody who is next!
4696                ActivityOptions.abort(options);
4697                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4698                return false;
4699            }
4700
4701            intent.setComponent(new ComponentName(
4702                    aInfo.applicationInfo.packageName, aInfo.name));
4703            intent.setFlags(intent.getFlags()&~(
4704                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4705                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4706                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4707                    Intent.FLAG_ACTIVITY_NEW_TASK));
4708
4709            // Okay now we need to start the new activity, replacing the
4710            // currently running activity.  This is a little tricky because
4711            // we want to start the new one as if the current one is finished,
4712            // but not finish the current one first so that there is no flicker.
4713            // And thus...
4714            final boolean wasFinishing = r.finishing;
4715            r.finishing = true;
4716
4717            // Propagate reply information over to the new activity.
4718            final ActivityRecord resultTo = r.resultTo;
4719            final String resultWho = r.resultWho;
4720            final int requestCode = r.requestCode;
4721            r.resultTo = null;
4722            if (resultTo != null) {
4723                resultTo.removeResultsLocked(r, resultWho, requestCode);
4724            }
4725
4726            final long origId = Binder.clearCallingIdentity();
4727            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4728                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4729                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4730                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4731                    false, false, null, null, null);
4732            Binder.restoreCallingIdentity(origId);
4733
4734            r.finishing = wasFinishing;
4735            if (res != ActivityManager.START_SUCCESS) {
4736                return false;
4737            }
4738            return true;
4739        }
4740    }
4741
4742    @Override
4743    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4744        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4745            String msg = "Permission Denial: startActivityFromRecents called without " +
4746                    START_TASKS_FROM_RECENTS;
4747            Slog.w(TAG, msg);
4748            throw new SecurityException(msg);
4749        }
4750        final long origId = Binder.clearCallingIdentity();
4751        try {
4752            synchronized (this) {
4753                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4754            }
4755        } finally {
4756            Binder.restoreCallingIdentity(origId);
4757        }
4758    }
4759
4760    final int startActivityInPackage(int uid, String callingPackage,
4761            Intent intent, String resolvedType, IBinder resultTo,
4762            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4763            IActivityContainer container, TaskRecord inTask) {
4764
4765        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4766                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4767
4768        // TODO: Switch to user app stacks here.
4769        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4770                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4771                null, null, null, bOptions, false, userId, container, inTask);
4772        return ret;
4773    }
4774
4775    @Override
4776    public final int startActivities(IApplicationThread caller, String callingPackage,
4777            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4778            int userId) {
4779        enforceNotIsolatedCaller("startActivities");
4780        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4781                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4782        // TODO: Switch to user app stacks here.
4783        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4784                resolvedTypes, resultTo, bOptions, userId);
4785        return ret;
4786    }
4787
4788    final int startActivitiesInPackage(int uid, String callingPackage,
4789            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4790            Bundle bOptions, int userId) {
4791
4792        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4793                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4794        // TODO: Switch to user app stacks here.
4795        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4796                resultTo, bOptions, userId);
4797        return ret;
4798    }
4799
4800    @Override
4801    public void reportActivityFullyDrawn(IBinder token) {
4802        synchronized (this) {
4803            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4804            if (r == null) {
4805                return;
4806            }
4807            r.reportFullyDrawnLocked();
4808        }
4809    }
4810
4811    @Override
4812    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4813        synchronized (this) {
4814            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4815            if (r == null) {
4816                return;
4817            }
4818            TaskRecord task = r.task;
4819            if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4820                // Fixed screen orientation isn't supported when activities aren't in full screen
4821                // mode.
4822                return;
4823            }
4824            final long origId = Binder.clearCallingIdentity();
4825            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4826            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4827                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4828            if (config != null) {
4829                r.frozenBeforeDestroy = true;
4830                if (!updateConfigurationLocked(config, r, false)) {
4831                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
4832                }
4833            }
4834            Binder.restoreCallingIdentity(origId);
4835        }
4836    }
4837
4838    @Override
4839    public int getRequestedOrientation(IBinder token) {
4840        synchronized (this) {
4841            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4842            if (r == null) {
4843                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4844            }
4845            return mWindowManager.getAppOrientation(r.appToken);
4846        }
4847    }
4848
4849    /**
4850     * This is the internal entry point for handling Activity.finish().
4851     *
4852     * @param token The Binder token referencing the Activity we want to finish.
4853     * @param resultCode Result code, if any, from this Activity.
4854     * @param resultData Result data (Intent), if any, from this Activity.
4855     * @param finishTask Whether to finish the task associated with this Activity.
4856     *
4857     * @return Returns true if the activity successfully finished, or false if it is still running.
4858     */
4859    @Override
4860    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4861            int finishTask) {
4862        // Refuse possible leaked file descriptors
4863        if (resultData != null && resultData.hasFileDescriptors() == true) {
4864            throw new IllegalArgumentException("File descriptors passed in Intent");
4865        }
4866
4867        synchronized(this) {
4868            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4869            if (r == null) {
4870                return true;
4871            }
4872            // Keep track of the root activity of the task before we finish it
4873            TaskRecord tr = r.task;
4874            ActivityRecord rootR = tr.getRootActivity();
4875            if (rootR == null) {
4876                Slog.w(TAG, "Finishing task with all activities already finished");
4877            }
4878            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4879            // finish.
4880            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4881                    mStackSupervisor.isLastLockedTask(tr)) {
4882                Slog.i(TAG, "Not finishing task in lock task mode");
4883                mStackSupervisor.showLockTaskToast();
4884                return false;
4885            }
4886            if (mController != null) {
4887                // Find the first activity that is not finishing.
4888                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4889                if (next != null) {
4890                    // ask watcher if this is allowed
4891                    boolean resumeOK = true;
4892                    try {
4893                        resumeOK = mController.activityResuming(next.packageName);
4894                    } catch (RemoteException e) {
4895                        mController = null;
4896                        Watchdog.getInstance().setActivityController(null);
4897                    }
4898
4899                    if (!resumeOK) {
4900                        Slog.i(TAG, "Not finishing activity because controller resumed");
4901                        return false;
4902                    }
4903                }
4904            }
4905            final long origId = Binder.clearCallingIdentity();
4906            try {
4907                boolean res;
4908                final boolean finishWithRootActivity =
4909                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4910                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4911                        || (finishWithRootActivity && r == rootR)) {
4912                    // If requested, remove the task that is associated to this activity only if it
4913                    // was the root activity in the task. The result code and data is ignored
4914                    // because we don't support returning them across task boundaries. Also, to
4915                    // keep backwards compatibility we remove the task from recents when finishing
4916                    // task with root activity.
4917                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4918                    if (!res) {
4919                        Slog.i(TAG, "Removing task failed to finish activity");
4920                    }
4921                } else {
4922                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4923                            resultData, "app-request", true);
4924                    if (!res) {
4925                        Slog.i(TAG, "Failed to finish by app-request");
4926                    }
4927                }
4928                return res;
4929            } finally {
4930                Binder.restoreCallingIdentity(origId);
4931            }
4932        }
4933    }
4934
4935    @Override
4936    public final void finishHeavyWeightApp() {
4937        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4938                != PackageManager.PERMISSION_GRANTED) {
4939            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4940                    + Binder.getCallingPid()
4941                    + ", uid=" + Binder.getCallingUid()
4942                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4943            Slog.w(TAG, msg);
4944            throw new SecurityException(msg);
4945        }
4946
4947        synchronized(this) {
4948            if (mHeavyWeightProcess == null) {
4949                return;
4950            }
4951
4952            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4953            for (int i = 0; i < activities.size(); i++) {
4954                ActivityRecord r = activities.get(i);
4955                if (!r.finishing && r.isInStackLocked()) {
4956                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4957                            null, "finish-heavy", true);
4958                }
4959            }
4960
4961            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4962                    mHeavyWeightProcess.userId, 0));
4963            mHeavyWeightProcess = null;
4964        }
4965    }
4966
4967    @Override
4968    public void crashApplication(int uid, int initialPid, String packageName,
4969            String message) {
4970        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4971                != PackageManager.PERMISSION_GRANTED) {
4972            String msg = "Permission Denial: crashApplication() from pid="
4973                    + Binder.getCallingPid()
4974                    + ", uid=" + Binder.getCallingUid()
4975                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4976            Slog.w(TAG, msg);
4977            throw new SecurityException(msg);
4978        }
4979
4980        synchronized(this) {
4981            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4982        }
4983    }
4984
4985    @Override
4986    public final void finishSubActivity(IBinder token, String resultWho,
4987            int requestCode) {
4988        synchronized(this) {
4989            final long origId = Binder.clearCallingIdentity();
4990            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4991            if (r != null) {
4992                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4993            }
4994            Binder.restoreCallingIdentity(origId);
4995        }
4996    }
4997
4998    @Override
4999    public boolean finishActivityAffinity(IBinder token) {
5000        synchronized(this) {
5001            final long origId = Binder.clearCallingIdentity();
5002            try {
5003                ActivityRecord r = ActivityRecord.isInStackLocked(token);
5004                if (r == null) {
5005                    return false;
5006                }
5007
5008                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
5009                // can finish.
5010                final TaskRecord task = r.task;
5011                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
5012                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
5013                    mStackSupervisor.showLockTaskToast();
5014                    return false;
5015                }
5016                return task.stack.finishActivityAffinityLocked(r);
5017            } finally {
5018                Binder.restoreCallingIdentity(origId);
5019            }
5020        }
5021    }
5022
5023    @Override
5024    public void finishVoiceTask(IVoiceInteractionSession session) {
5025        synchronized (this) {
5026            final long origId = Binder.clearCallingIdentity();
5027            try {
5028                // TODO: VI Consider treating local voice interactions and voice tasks
5029                // differently here
5030                mStackSupervisor.finishVoiceTask(session);
5031            } finally {
5032                Binder.restoreCallingIdentity(origId);
5033            }
5034        }
5035
5036    }
5037
5038    @Override
5039    public boolean releaseActivityInstance(IBinder token) {
5040        synchronized(this) {
5041            final long origId = Binder.clearCallingIdentity();
5042            try {
5043                ActivityRecord r = ActivityRecord.isInStackLocked(token);
5044                if (r == null) {
5045                    return false;
5046                }
5047                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
5048            } finally {
5049                Binder.restoreCallingIdentity(origId);
5050            }
5051        }
5052    }
5053
5054    @Override
5055    public void releaseSomeActivities(IApplicationThread appInt) {
5056        synchronized(this) {
5057            final long origId = Binder.clearCallingIdentity();
5058            try {
5059                ProcessRecord app = getRecordForAppLocked(appInt);
5060                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5061            } finally {
5062                Binder.restoreCallingIdentity(origId);
5063            }
5064        }
5065    }
5066
5067    @Override
5068    public boolean willActivityBeVisible(IBinder token) {
5069        synchronized(this) {
5070            ActivityStack stack = ActivityRecord.getStackLocked(token);
5071            if (stack != null) {
5072                return stack.willActivityBeVisibleLocked(token);
5073            }
5074            return false;
5075        }
5076    }
5077
5078    @Override
5079    public void overridePendingTransition(IBinder token, String packageName,
5080            int enterAnim, int exitAnim) {
5081        synchronized(this) {
5082            ActivityRecord self = ActivityRecord.isInStackLocked(token);
5083            if (self == null) {
5084                return;
5085            }
5086
5087            final long origId = Binder.clearCallingIdentity();
5088
5089            if (self.state == ActivityState.RESUMED
5090                    || self.state == ActivityState.PAUSING) {
5091                mWindowManager.overridePendingAppTransition(packageName,
5092                        enterAnim, exitAnim, null);
5093            }
5094
5095            Binder.restoreCallingIdentity(origId);
5096        }
5097    }
5098
5099    /**
5100     * Main function for removing an existing process from the activity manager
5101     * as a result of that process going away.  Clears out all connections
5102     * to the process.
5103     */
5104    private final void handleAppDiedLocked(ProcessRecord app,
5105            boolean restarting, boolean allowRestart) {
5106        int pid = app.pid;
5107        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5108                false /*replacingPid*/);
5109        if (!kept && !restarting) {
5110            removeLruProcessLocked(app);
5111            if (pid > 0) {
5112                ProcessList.remove(pid);
5113            }
5114        }
5115
5116        if (mProfileProc == app) {
5117            clearProfilerLocked();
5118        }
5119
5120        // Remove this application's activities from active lists.
5121        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5122
5123        app.activities.clear();
5124
5125        if (app.instrumentationClass != null) {
5126            Slog.w(TAG, "Crash of app " + app.processName
5127                  + " running instrumentation " + app.instrumentationClass);
5128            Bundle info = new Bundle();
5129            info.putString("shortMsg", "Process crashed.");
5130            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5131        }
5132
5133        if (!restarting && hasVisibleActivities
5134                && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5135            // If there was nothing to resume, and we are not already restarting this process, but
5136            // there is a visible activity that is hosted by the process...  then make sure all
5137            // visible activities are running, taking care of restarting this process.
5138            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5139        }
5140    }
5141
5142    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5143        IBinder threadBinder = thread.asBinder();
5144        // Find the application record.
5145        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5146            ProcessRecord rec = mLruProcesses.get(i);
5147            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5148                return i;
5149            }
5150        }
5151        return -1;
5152    }
5153
5154    final ProcessRecord getRecordForAppLocked(
5155            IApplicationThread thread) {
5156        if (thread == null) {
5157            return null;
5158        }
5159
5160        int appIndex = getLRURecordIndexForAppLocked(thread);
5161        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
5162    }
5163
5164    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5165        // If there are no longer any background processes running,
5166        // and the app that died was not running instrumentation,
5167        // then tell everyone we are now low on memory.
5168        boolean haveBg = false;
5169        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5170            ProcessRecord rec = mLruProcesses.get(i);
5171            if (rec.thread != null
5172                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5173                haveBg = true;
5174                break;
5175            }
5176        }
5177
5178        if (!haveBg) {
5179            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5180            if (doReport) {
5181                long now = SystemClock.uptimeMillis();
5182                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5183                    doReport = false;
5184                } else {
5185                    mLastMemUsageReportTime = now;
5186                }
5187            }
5188            final ArrayList<ProcessMemInfo> memInfos
5189                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5190            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5191            long now = SystemClock.uptimeMillis();
5192            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5193                ProcessRecord rec = mLruProcesses.get(i);
5194                if (rec == dyingProc || rec.thread == null) {
5195                    continue;
5196                }
5197                if (doReport) {
5198                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5199                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5200                }
5201                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5202                    // The low memory report is overriding any current
5203                    // state for a GC request.  Make sure to do
5204                    // heavy/important/visible/foreground processes first.
5205                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5206                        rec.lastRequestedGc = 0;
5207                    } else {
5208                        rec.lastRequestedGc = rec.lastLowMemory;
5209                    }
5210                    rec.reportLowMemory = true;
5211                    rec.lastLowMemory = now;
5212                    mProcessesToGc.remove(rec);
5213                    addProcessToGcListLocked(rec);
5214                }
5215            }
5216            if (doReport) {
5217                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5218                mHandler.sendMessage(msg);
5219            }
5220            scheduleAppGcsLocked();
5221        }
5222    }
5223
5224    final void appDiedLocked(ProcessRecord app) {
5225       appDiedLocked(app, app.pid, app.thread, false);
5226    }
5227
5228    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5229            boolean fromBinderDied) {
5230        // First check if this ProcessRecord is actually active for the pid.
5231        synchronized (mPidsSelfLocked) {
5232            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5233            if (curProc != app) {
5234                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5235                return;
5236            }
5237        }
5238
5239        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5240        synchronized (stats) {
5241            stats.noteProcessDiedLocked(app.info.uid, pid);
5242        }
5243
5244        if (!app.killed) {
5245            if (!fromBinderDied) {
5246                Process.killProcessQuiet(pid);
5247            }
5248            killProcessGroup(app.uid, pid);
5249            app.killed = true;
5250        }
5251
5252        // Clean up already done if the process has been re-started.
5253        if (app.pid == pid && app.thread != null &&
5254                app.thread.asBinder() == thread.asBinder()) {
5255            boolean doLowMem = app.instrumentationClass == null;
5256            boolean doOomAdj = doLowMem;
5257            if (!app.killedByAm) {
5258                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5259                        + ") has died");
5260                mAllowLowerMemLevel = true;
5261            } else {
5262                // Note that we always want to do oom adj to update our state with the
5263                // new number of procs.
5264                mAllowLowerMemLevel = false;
5265                doLowMem = false;
5266            }
5267            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5268            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5269                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5270            handleAppDiedLocked(app, false, true);
5271
5272            if (doOomAdj) {
5273                updateOomAdjLocked();
5274            }
5275            if (doLowMem) {
5276                doLowMemReportIfNeededLocked(app);
5277            }
5278        } else if (app.pid != pid) {
5279            // A new process has already been started.
5280            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5281                    + ") has died and restarted (pid " + app.pid + ").");
5282            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5283        } else if (DEBUG_PROCESSES) {
5284            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5285                    + thread.asBinder());
5286        }
5287    }
5288
5289    /**
5290     * If a stack trace dump file is configured, dump process stack traces.
5291     * @param clearTraces causes the dump file to be erased prior to the new
5292     *    traces being written, if true; when false, the new traces will be
5293     *    appended to any existing file content.
5294     * @param firstPids of dalvik VM processes to dump stack traces for first
5295     * @param lastPids of dalvik VM processes to dump stack traces for last
5296     * @param nativeProcs optional list of native process names to dump stack crawls
5297     * @return file containing stack traces, or null if no dump file is configured
5298     */
5299    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5300            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5301        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5302        if (tracesPath == null || tracesPath.length() == 0) {
5303            return null;
5304        }
5305
5306        File tracesFile = new File(tracesPath);
5307        try {
5308            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5309            tracesFile.createNewFile();
5310            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5311        } catch (IOException e) {
5312            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5313            return null;
5314        }
5315
5316        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5317        return tracesFile;
5318    }
5319
5320    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5321            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5322        // Use a FileObserver to detect when traces finish writing.
5323        // The order of traces is considered important to maintain for legibility.
5324        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5325            @Override
5326            public synchronized void onEvent(int event, String path) { notify(); }
5327        };
5328
5329        try {
5330            observer.startWatching();
5331
5332            // First collect all of the stacks of the most important pids.
5333            if (firstPids != null) {
5334                try {
5335                    int num = firstPids.size();
5336                    for (int i = 0; i < num; i++) {
5337                        synchronized (observer) {
5338                            if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5339                                    + firstPids.get(i));
5340                            final long sime = SystemClock.elapsedRealtime();
5341                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5342                            observer.wait(1000);  // Wait for write-close, give up after 1 sec
5343                            if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5344                                    + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5345                        }
5346                    }
5347                } catch (InterruptedException e) {
5348                    Slog.wtf(TAG, e);
5349                }
5350            }
5351
5352            // Next collect the stacks of the native pids
5353            if (nativeProcs != null) {
5354                int[] pids = Process.getPidsForCommands(nativeProcs);
5355                if (pids != null) {
5356                    for (int pid : pids) {
5357                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5358                        final long sime = SystemClock.elapsedRealtime();
5359                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5360                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5361                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5362                    }
5363                }
5364            }
5365
5366            // Lastly, measure CPU usage.
5367            if (processCpuTracker != null) {
5368                processCpuTracker.init();
5369                System.gc();
5370                processCpuTracker.update();
5371                try {
5372                    synchronized (processCpuTracker) {
5373                        processCpuTracker.wait(500); // measure over 1/2 second.
5374                    }
5375                } catch (InterruptedException e) {
5376                }
5377                processCpuTracker.update();
5378
5379                // We'll take the stack crawls of just the top apps using CPU.
5380                final int N = processCpuTracker.countWorkingStats();
5381                int numProcs = 0;
5382                for (int i=0; i<N && numProcs<5; i++) {
5383                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5384                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5385                        numProcs++;
5386                        try {
5387                            synchronized (observer) {
5388                                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5389                                        + stats.pid);
5390                                final long stime = SystemClock.elapsedRealtime();
5391                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5392                                observer.wait(1000);  // Wait for write-close, give up after 1 sec
5393                                if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5394                                        + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5395                            }
5396                        } catch (InterruptedException e) {
5397                            Slog.wtf(TAG, e);
5398                        }
5399                    } else if (DEBUG_ANR) {
5400                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5401                                + stats.pid);
5402                    }
5403                }
5404            }
5405        } finally {
5406            observer.stopWatching();
5407        }
5408    }
5409
5410    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5411        if (true || IS_USER_BUILD) {
5412            return;
5413        }
5414        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5415        if (tracesPath == null || tracesPath.length() == 0) {
5416            return;
5417        }
5418
5419        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5420        StrictMode.allowThreadDiskWrites();
5421        try {
5422            final File tracesFile = new File(tracesPath);
5423            final File tracesDir = tracesFile.getParentFile();
5424            final File tracesTmp = new File(tracesDir, "__tmp__");
5425            try {
5426                if (tracesFile.exists()) {
5427                    tracesTmp.delete();
5428                    tracesFile.renameTo(tracesTmp);
5429                }
5430                StringBuilder sb = new StringBuilder();
5431                Time tobj = new Time();
5432                tobj.set(System.currentTimeMillis());
5433                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5434                sb.append(": ");
5435                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5436                sb.append(" since ");
5437                sb.append(msg);
5438                FileOutputStream fos = new FileOutputStream(tracesFile);
5439                fos.write(sb.toString().getBytes());
5440                if (app == null) {
5441                    fos.write("\n*** No application process!".getBytes());
5442                }
5443                fos.close();
5444                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5445            } catch (IOException e) {
5446                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5447                return;
5448            }
5449
5450            if (app != null) {
5451                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5452                firstPids.add(app.pid);
5453                dumpStackTraces(tracesPath, firstPids, null, null, null);
5454            }
5455
5456            File lastTracesFile = null;
5457            File curTracesFile = null;
5458            for (int i=9; i>=0; i--) {
5459                String name = String.format(Locale.US, "slow%02d.txt", i);
5460                curTracesFile = new File(tracesDir, name);
5461                if (curTracesFile.exists()) {
5462                    if (lastTracesFile != null) {
5463                        curTracesFile.renameTo(lastTracesFile);
5464                    } else {
5465                        curTracesFile.delete();
5466                    }
5467                }
5468                lastTracesFile = curTracesFile;
5469            }
5470            tracesFile.renameTo(curTracesFile);
5471            if (tracesTmp.exists()) {
5472                tracesTmp.renameTo(tracesFile);
5473            }
5474        } finally {
5475            StrictMode.setThreadPolicy(oldPolicy);
5476        }
5477    }
5478
5479    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5480        if (!mLaunchWarningShown) {
5481            mLaunchWarningShown = true;
5482            mUiHandler.post(new Runnable() {
5483                @Override
5484                public void run() {
5485                    synchronized (ActivityManagerService.this) {
5486                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5487                        d.show();
5488                        mUiHandler.postDelayed(new Runnable() {
5489                            @Override
5490                            public void run() {
5491                                synchronized (ActivityManagerService.this) {
5492                                    d.dismiss();
5493                                    mLaunchWarningShown = false;
5494                                }
5495                            }
5496                        }, 4000);
5497                    }
5498                }
5499            });
5500        }
5501    }
5502
5503    @Override
5504    public boolean clearApplicationUserData(final String packageName,
5505            final IPackageDataObserver observer, int userId) {
5506        enforceNotIsolatedCaller("clearApplicationUserData");
5507        int uid = Binder.getCallingUid();
5508        int pid = Binder.getCallingPid();
5509        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5510                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5511
5512
5513        long callingId = Binder.clearCallingIdentity();
5514        try {
5515            IPackageManager pm = AppGlobals.getPackageManager();
5516            int pkgUid = -1;
5517            synchronized(this) {
5518                if (getPackageManagerInternalLocked().isPackageDataProtected(
5519                        userId, packageName)) {
5520                    throw new SecurityException(
5521                            "Cannot clear data for a protected package: " + packageName);
5522                }
5523
5524                try {
5525                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5526                } catch (RemoteException e) {
5527                }
5528                if (pkgUid == -1) {
5529                    Slog.w(TAG, "Invalid packageName: " + packageName);
5530                    if (observer != null) {
5531                        try {
5532                            observer.onRemoveCompleted(packageName, false);
5533                        } catch (RemoteException e) {
5534                            Slog.i(TAG, "Observer no longer exists.");
5535                        }
5536                    }
5537                    return false;
5538                }
5539                if (uid == pkgUid || checkComponentPermission(
5540                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5541                        pid, uid, -1, true)
5542                        == PackageManager.PERMISSION_GRANTED) {
5543                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5544                } else {
5545                    throw new SecurityException("PID " + pid + " does not have permission "
5546                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5547                                    + " of package " + packageName);
5548                }
5549
5550                // Remove all tasks match the cleared application package and user
5551                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5552                    final TaskRecord tr = mRecentTasks.get(i);
5553                    final String taskPackageName =
5554                            tr.getBaseIntent().getComponent().getPackageName();
5555                    if (tr.userId != userId) continue;
5556                    if (!taskPackageName.equals(packageName)) continue;
5557                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5558                }
5559            }
5560
5561            final int pkgUidF = pkgUid;
5562            final int userIdF = userId;
5563            final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5564                @Override
5565                public void onRemoveCompleted(String packageName, boolean succeeded)
5566                        throws RemoteException {
5567                    synchronized (ActivityManagerService.this) {
5568                        finishForceStopPackageLocked(packageName, pkgUidF);
5569                    }
5570
5571                    final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5572                            Uri.fromParts("package", packageName, null));
5573                    intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5574                    intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5575                    broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5576                            null, null, 0, null, null, null, null, false, false, userIdF);
5577
5578                    if (observer != null) {
5579                        observer.onRemoveCompleted(packageName, succeeded);
5580                    }
5581                }
5582            };
5583
5584            try {
5585                // Clear application user data
5586                pm.clearApplicationUserData(packageName, localObserver, userId);
5587
5588                synchronized(this) {
5589                    // Remove all permissions granted from/to this package
5590                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5591                }
5592
5593                // Remove all zen rules created by this package; revoke it's zen access.
5594                INotificationManager inm = NotificationManager.getService();
5595                inm.removeAutomaticZenRules(packageName);
5596                inm.setNotificationPolicyAccessGranted(packageName, false);
5597
5598            } catch (RemoteException e) {
5599            }
5600        } finally {
5601            Binder.restoreCallingIdentity(callingId);
5602        }
5603        return true;
5604    }
5605
5606    @Override
5607    public void killBackgroundProcesses(final String packageName, int userId) {
5608        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5609                != PackageManager.PERMISSION_GRANTED &&
5610                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5611                        != PackageManager.PERMISSION_GRANTED) {
5612            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5613                    + Binder.getCallingPid()
5614                    + ", uid=" + Binder.getCallingUid()
5615                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5616            Slog.w(TAG, msg);
5617            throw new SecurityException(msg);
5618        }
5619
5620        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5621                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5622        long callingId = Binder.clearCallingIdentity();
5623        try {
5624            IPackageManager pm = AppGlobals.getPackageManager();
5625            synchronized(this) {
5626                int appId = -1;
5627                try {
5628                    appId = UserHandle.getAppId(
5629                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5630                } catch (RemoteException e) {
5631                }
5632                if (appId == -1) {
5633                    Slog.w(TAG, "Invalid packageName: " + packageName);
5634                    return;
5635                }
5636                killPackageProcessesLocked(packageName, appId, userId,
5637                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5638            }
5639        } finally {
5640            Binder.restoreCallingIdentity(callingId);
5641        }
5642    }
5643
5644    @Override
5645    public void killAllBackgroundProcesses() {
5646        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5647                != PackageManager.PERMISSION_GRANTED) {
5648            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5649                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5650                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5651            Slog.w(TAG, msg);
5652            throw new SecurityException(msg);
5653        }
5654
5655        final long callingId = Binder.clearCallingIdentity();
5656        try {
5657            synchronized (this) {
5658                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5659                final int NP = mProcessNames.getMap().size();
5660                for (int ip = 0; ip < NP; ip++) {
5661                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5662                    final int NA = apps.size();
5663                    for (int ia = 0; ia < NA; ia++) {
5664                        final ProcessRecord app = apps.valueAt(ia);
5665                        if (app.persistent) {
5666                            // We don't kill persistent processes.
5667                            continue;
5668                        }
5669                        if (app.removed) {
5670                            procs.add(app);
5671                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5672                            app.removed = true;
5673                            procs.add(app);
5674                        }
5675                    }
5676                }
5677
5678                final int N = procs.size();
5679                for (int i = 0; i < N; i++) {
5680                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5681                }
5682
5683                mAllowLowerMemLevel = true;
5684
5685                updateOomAdjLocked();
5686                doLowMemReportIfNeededLocked(null);
5687            }
5688        } finally {
5689            Binder.restoreCallingIdentity(callingId);
5690        }
5691    }
5692
5693    /**
5694     * Kills all background processes, except those matching any of the
5695     * specified properties.
5696     *
5697     * @param minTargetSdk the target SDK version at or above which to preserve
5698     *                     processes, or {@code -1} to ignore the target SDK
5699     * @param maxProcState the process state at or below which to preserve
5700     *                     processes, or {@code -1} to ignore the process state
5701     */
5702    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5703        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5704                != PackageManager.PERMISSION_GRANTED) {
5705            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5706                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5707                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5708            Slog.w(TAG, msg);
5709            throw new SecurityException(msg);
5710        }
5711
5712        final long callingId = Binder.clearCallingIdentity();
5713        try {
5714            synchronized (this) {
5715                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5716                final int NP = mProcessNames.getMap().size();
5717                for (int ip = 0; ip < NP; ip++) {
5718                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5719                    final int NA = apps.size();
5720                    for (int ia = 0; ia < NA; ia++) {
5721                        final ProcessRecord app = apps.valueAt(ia);
5722                        if (app.removed) {
5723                            procs.add(app);
5724                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5725                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5726                            app.removed = true;
5727                            procs.add(app);
5728                        }
5729                    }
5730                }
5731
5732                final int N = procs.size();
5733                for (int i = 0; i < N; i++) {
5734                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5735                }
5736            }
5737        } finally {
5738            Binder.restoreCallingIdentity(callingId);
5739        }
5740    }
5741
5742    @Override
5743    public void forceStopPackage(final String packageName, int userId) {
5744        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5745                != PackageManager.PERMISSION_GRANTED) {
5746            String msg = "Permission Denial: forceStopPackage() from pid="
5747                    + Binder.getCallingPid()
5748                    + ", uid=" + Binder.getCallingUid()
5749                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5750            Slog.w(TAG, msg);
5751            throw new SecurityException(msg);
5752        }
5753        final int callingPid = Binder.getCallingPid();
5754        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5755                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5756        long callingId = Binder.clearCallingIdentity();
5757        try {
5758            IPackageManager pm = AppGlobals.getPackageManager();
5759            synchronized(this) {
5760                int[] users = userId == UserHandle.USER_ALL
5761                        ? mUserController.getUsers() : new int[] { userId };
5762                for (int user : users) {
5763                    int pkgUid = -1;
5764                    try {
5765                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5766                                user);
5767                    } catch (RemoteException e) {
5768                    }
5769                    if (pkgUid == -1) {
5770                        Slog.w(TAG, "Invalid packageName: " + packageName);
5771                        continue;
5772                    }
5773                    try {
5774                        pm.setPackageStoppedState(packageName, true, user);
5775                    } catch (RemoteException e) {
5776                    } catch (IllegalArgumentException e) {
5777                        Slog.w(TAG, "Failed trying to unstop package "
5778                                + packageName + ": " + e);
5779                    }
5780                    if (mUserController.isUserRunningLocked(user, 0)) {
5781                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5782                        finishForceStopPackageLocked(packageName, pkgUid);
5783                    }
5784                }
5785            }
5786        } finally {
5787            Binder.restoreCallingIdentity(callingId);
5788        }
5789    }
5790
5791    @Override
5792    public void addPackageDependency(String packageName) {
5793        synchronized (this) {
5794            int callingPid = Binder.getCallingPid();
5795            if (callingPid == Process.myPid()) {
5796                //  Yeah, um, no.
5797                return;
5798            }
5799            ProcessRecord proc;
5800            synchronized (mPidsSelfLocked) {
5801                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5802            }
5803            if (proc != null) {
5804                if (proc.pkgDeps == null) {
5805                    proc.pkgDeps = new ArraySet<String>(1);
5806                }
5807                proc.pkgDeps.add(packageName);
5808            }
5809        }
5810    }
5811
5812    /*
5813     * The pkg name and app id have to be specified.
5814     */
5815    @Override
5816    public void killApplication(String pkg, int appId, int userId, String reason) {
5817        if (pkg == null) {
5818            return;
5819        }
5820        // Make sure the uid is valid.
5821        if (appId < 0) {
5822            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5823            return;
5824        }
5825        int callerUid = Binder.getCallingUid();
5826        // Only the system server can kill an application
5827        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5828            // Post an aysnc message to kill the application
5829            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5830            msg.arg1 = appId;
5831            msg.arg2 = userId;
5832            Bundle bundle = new Bundle();
5833            bundle.putString("pkg", pkg);
5834            bundle.putString("reason", reason);
5835            msg.obj = bundle;
5836            mHandler.sendMessage(msg);
5837        } else {
5838            throw new SecurityException(callerUid + " cannot kill pkg: " +
5839                    pkg);
5840        }
5841    }
5842
5843    @Override
5844    public void closeSystemDialogs(String reason) {
5845        enforceNotIsolatedCaller("closeSystemDialogs");
5846
5847        final int pid = Binder.getCallingPid();
5848        final int uid = Binder.getCallingUid();
5849        final long origId = Binder.clearCallingIdentity();
5850        try {
5851            synchronized (this) {
5852                // Only allow this from foreground processes, so that background
5853                // applications can't abuse it to prevent system UI from being shown.
5854                if (uid >= Process.FIRST_APPLICATION_UID) {
5855                    ProcessRecord proc;
5856                    synchronized (mPidsSelfLocked) {
5857                        proc = mPidsSelfLocked.get(pid);
5858                    }
5859                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5860                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5861                                + " from background process " + proc);
5862                        return;
5863                    }
5864                }
5865                closeSystemDialogsLocked(reason);
5866            }
5867        } finally {
5868            Binder.restoreCallingIdentity(origId);
5869        }
5870    }
5871
5872    void closeSystemDialogsLocked(String reason) {
5873        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5874        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5875                | Intent.FLAG_RECEIVER_FOREGROUND);
5876        if (reason != null) {
5877            intent.putExtra("reason", reason);
5878        }
5879        mWindowManager.closeSystemDialogs(reason);
5880
5881        mStackSupervisor.closeSystemDialogsLocked();
5882
5883        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5884                AppOpsManager.OP_NONE, null, false, false,
5885                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5886    }
5887
5888    @Override
5889    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5890        enforceNotIsolatedCaller("getProcessMemoryInfo");
5891        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5892        for (int i=pids.length-1; i>=0; i--) {
5893            ProcessRecord proc;
5894            int oomAdj;
5895            synchronized (this) {
5896                synchronized (mPidsSelfLocked) {
5897                    proc = mPidsSelfLocked.get(pids[i]);
5898                    oomAdj = proc != null ? proc.setAdj : 0;
5899                }
5900            }
5901            infos[i] = new Debug.MemoryInfo();
5902            Debug.getMemoryInfo(pids[i], infos[i]);
5903            if (proc != null) {
5904                synchronized (this) {
5905                    if (proc.thread != null && proc.setAdj == oomAdj) {
5906                        // Record this for posterity if the process has been stable.
5907                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5908                                infos[i].getTotalUss(), false, proc.pkgList);
5909                    }
5910                }
5911            }
5912        }
5913        return infos;
5914    }
5915
5916    @Override
5917    public long[] getProcessPss(int[] pids) {
5918        enforceNotIsolatedCaller("getProcessPss");
5919        long[] pss = new long[pids.length];
5920        for (int i=pids.length-1; i>=0; i--) {
5921            ProcessRecord proc;
5922            int oomAdj;
5923            synchronized (this) {
5924                synchronized (mPidsSelfLocked) {
5925                    proc = mPidsSelfLocked.get(pids[i]);
5926                    oomAdj = proc != null ? proc.setAdj : 0;
5927                }
5928            }
5929            long[] tmpUss = new long[1];
5930            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5931            if (proc != null) {
5932                synchronized (this) {
5933                    if (proc.thread != null && proc.setAdj == oomAdj) {
5934                        // Record this for posterity if the process has been stable.
5935                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5936                    }
5937                }
5938            }
5939        }
5940        return pss;
5941    }
5942
5943    @Override
5944    public void killApplicationProcess(String processName, int uid) {
5945        if (processName == null) {
5946            return;
5947        }
5948
5949        int callerUid = Binder.getCallingUid();
5950        // Only the system server can kill an application
5951        if (callerUid == Process.SYSTEM_UID) {
5952            synchronized (this) {
5953                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5954                if (app != null && app.thread != null) {
5955                    try {
5956                        app.thread.scheduleSuicide();
5957                    } catch (RemoteException e) {
5958                        // If the other end already died, then our work here is done.
5959                    }
5960                } else {
5961                    Slog.w(TAG, "Process/uid not found attempting kill of "
5962                            + processName + " / " + uid);
5963                }
5964            }
5965        } else {
5966            throw new SecurityException(callerUid + " cannot kill app process: " +
5967                    processName);
5968        }
5969    }
5970
5971    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5972        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5973                false, true, false, false, UserHandle.getUserId(uid), reason);
5974    }
5975
5976    private void finishForceStopPackageLocked(final String packageName, int uid) {
5977        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5978                Uri.fromParts("package", packageName, null));
5979        if (!mProcessesReady) {
5980            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5981                    | Intent.FLAG_RECEIVER_FOREGROUND);
5982        }
5983        intent.putExtra(Intent.EXTRA_UID, uid);
5984        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5985        broadcastIntentLocked(null, null, intent,
5986                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5987                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5988    }
5989
5990
5991    private final boolean killPackageProcessesLocked(String packageName, int appId,
5992            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5993            boolean doit, boolean evenPersistent, String reason) {
5994        ArrayList<ProcessRecord> procs = new ArrayList<>();
5995
5996        // Remove all processes this package may have touched: all with the
5997        // same UID (except for the system or root user), and all whose name
5998        // matches the package name.
5999        final int NP = mProcessNames.getMap().size();
6000        for (int ip=0; ip<NP; ip++) {
6001            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6002            final int NA = apps.size();
6003            for (int ia=0; ia<NA; ia++) {
6004                ProcessRecord app = apps.valueAt(ia);
6005                if (app.persistent && !evenPersistent) {
6006                    // we don't kill persistent processes
6007                    continue;
6008                }
6009                if (app.removed) {
6010                    if (doit) {
6011                        procs.add(app);
6012                    }
6013                    continue;
6014                }
6015
6016                // Skip process if it doesn't meet our oom adj requirement.
6017                if (app.setAdj < minOomAdj) {
6018                    continue;
6019                }
6020
6021                // If no package is specified, we call all processes under the
6022                // give user id.
6023                if (packageName == null) {
6024                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
6025                        continue;
6026                    }
6027                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
6028                        continue;
6029                    }
6030                // Package has been specified, we want to hit all processes
6031                // that match it.  We need to qualify this by the processes
6032                // that are running under the specified app and user ID.
6033                } else {
6034                    final boolean isDep = app.pkgDeps != null
6035                            && app.pkgDeps.contains(packageName);
6036                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
6037                        continue;
6038                    }
6039                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
6040                        continue;
6041                    }
6042                    if (!app.pkgList.containsKey(packageName) && !isDep) {
6043                        continue;
6044                    }
6045                }
6046
6047                // Process has passed all conditions, kill it!
6048                if (!doit) {
6049                    return true;
6050                }
6051                app.removed = true;
6052                procs.add(app);
6053            }
6054        }
6055
6056        int N = procs.size();
6057        for (int i=0; i<N; i++) {
6058            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
6059        }
6060        updateOomAdjLocked();
6061        return N > 0;
6062    }
6063
6064    private void cleanupDisabledPackageComponentsLocked(
6065            String packageName, int userId, boolean killProcess, String[] changedClasses) {
6066
6067        Set<String> disabledClasses = null;
6068        boolean packageDisabled = false;
6069        IPackageManager pm = AppGlobals.getPackageManager();
6070
6071        if (changedClasses == null) {
6072            // Nothing changed...
6073            return;
6074        }
6075
6076        // Determine enable/disable state of the package and its components.
6077        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6078        for (int i = changedClasses.length - 1; i >= 0; i--) {
6079            final String changedClass = changedClasses[i];
6080
6081            if (changedClass.equals(packageName)) {
6082                try {
6083                    // Entire package setting changed
6084                    enabled = pm.getApplicationEnabledSetting(packageName,
6085                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6086                } catch (Exception e) {
6087                    // No such package/component; probably racing with uninstall.  In any
6088                    // event it means we have nothing further to do here.
6089                    return;
6090                }
6091                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6092                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6093                if (packageDisabled) {
6094                    // Entire package is disabled.
6095                    // No need to continue to check component states.
6096                    disabledClasses = null;
6097                    break;
6098                }
6099            } else {
6100                try {
6101                    enabled = pm.getComponentEnabledSetting(
6102                            new ComponentName(packageName, changedClass),
6103                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6104                } catch (Exception e) {
6105                    // As above, probably racing with uninstall.
6106                    return;
6107                }
6108                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6109                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6110                    if (disabledClasses == null) {
6111                        disabledClasses = new ArraySet<>(changedClasses.length);
6112                    }
6113                    disabledClasses.add(changedClass);
6114                }
6115            }
6116        }
6117
6118        if (!packageDisabled && disabledClasses == null) {
6119            // Nothing to do here...
6120            return;
6121        }
6122
6123        // Clean-up disabled activities.
6124        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6125                packageName, disabledClasses, true, false, userId) && mBooted) {
6126            mStackSupervisor.resumeFocusedStackTopActivityLocked();
6127            mStackSupervisor.scheduleIdleLocked();
6128        }
6129
6130        // Clean-up disabled tasks
6131        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6132
6133        // Clean-up disabled services.
6134        mServices.bringDownDisabledPackageServicesLocked(
6135                packageName, disabledClasses, userId, false, killProcess, true);
6136
6137        // Clean-up disabled providers.
6138        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6139        mProviderMap.collectPackageProvidersLocked(
6140                packageName, disabledClasses, true, false, userId, providers);
6141        for (int i = providers.size() - 1; i >= 0; i--) {
6142            removeDyingProviderLocked(null, providers.get(i), true);
6143        }
6144
6145        // Clean-up disabled broadcast receivers.
6146        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6147            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6148                    packageName, disabledClasses, userId, true);
6149        }
6150
6151    }
6152
6153    final boolean clearBroadcastQueueForUserLocked(int userId) {
6154        boolean didSomething = false;
6155        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6156            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6157                    null, null, userId, true);
6158        }
6159        return didSomething;
6160    }
6161
6162    final boolean forceStopPackageLocked(String packageName, int appId,
6163            boolean callerWillRestart, boolean purgeCache, boolean doit,
6164            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6165        int i;
6166
6167        if (userId == UserHandle.USER_ALL && packageName == null) {
6168            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6169        }
6170
6171        if (appId < 0 && packageName != null) {
6172            try {
6173                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6174                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6175            } catch (RemoteException e) {
6176            }
6177        }
6178
6179        if (doit) {
6180            if (packageName != null) {
6181                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6182                        + " user=" + userId + ": " + reason);
6183            } else {
6184                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6185            }
6186
6187            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6188        }
6189
6190        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6191                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6192                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6193
6194        didSomething |= mActivityStarter.clearPendingActivityLaunchesLocked(packageName);
6195
6196        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6197                packageName, null, doit, evenPersistent, userId)) {
6198            if (!doit) {
6199                return true;
6200            }
6201            didSomething = true;
6202        }
6203
6204        if (mServices.bringDownDisabledPackageServicesLocked(
6205                packageName, null, userId, evenPersistent, true, doit)) {
6206            if (!doit) {
6207                return true;
6208            }
6209            didSomething = true;
6210        }
6211
6212        if (packageName == null) {
6213            // Remove all sticky broadcasts from this user.
6214            mStickyBroadcasts.remove(userId);
6215        }
6216
6217        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6218        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6219                userId, providers)) {
6220            if (!doit) {
6221                return true;
6222            }
6223            didSomething = true;
6224        }
6225        for (i = providers.size() - 1; i >= 0; i--) {
6226            removeDyingProviderLocked(null, providers.get(i), true);
6227        }
6228
6229        // Remove transient permissions granted from/to this package/user
6230        removeUriPermissionsForPackageLocked(packageName, userId, false);
6231
6232        if (doit) {
6233            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6234                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6235                        packageName, null, userId, doit);
6236            }
6237        }
6238
6239        if (packageName == null || uninstalling) {
6240            // Remove pending intents.  For now we only do this when force
6241            // stopping users, because we have some problems when doing this
6242            // for packages -- app widgets are not currently cleaned up for
6243            // such packages, so they can be left with bad pending intents.
6244            if (mIntentSenderRecords.size() > 0) {
6245                Iterator<WeakReference<PendingIntentRecord>> it
6246                        = mIntentSenderRecords.values().iterator();
6247                while (it.hasNext()) {
6248                    WeakReference<PendingIntentRecord> wpir = it.next();
6249                    if (wpir == null) {
6250                        it.remove();
6251                        continue;
6252                    }
6253                    PendingIntentRecord pir = wpir.get();
6254                    if (pir == null) {
6255                        it.remove();
6256                        continue;
6257                    }
6258                    if (packageName == null) {
6259                        // Stopping user, remove all objects for the user.
6260                        if (pir.key.userId != userId) {
6261                            // Not the same user, skip it.
6262                            continue;
6263                        }
6264                    } else {
6265                        if (UserHandle.getAppId(pir.uid) != appId) {
6266                            // Different app id, skip it.
6267                            continue;
6268                        }
6269                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6270                            // Different user, skip it.
6271                            continue;
6272                        }
6273                        if (!pir.key.packageName.equals(packageName)) {
6274                            // Different package, skip it.
6275                            continue;
6276                        }
6277                    }
6278                    if (!doit) {
6279                        return true;
6280                    }
6281                    didSomething = true;
6282                    it.remove();
6283                    pir.canceled = true;
6284                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6285                        pir.key.activity.pendingResults.remove(pir.ref);
6286                    }
6287                }
6288            }
6289        }
6290
6291        if (doit) {
6292            if (purgeCache && packageName != null) {
6293                AttributeCache ac = AttributeCache.instance();
6294                if (ac != null) {
6295                    ac.removePackage(packageName);
6296                }
6297            }
6298            if (mBooted) {
6299                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6300                mStackSupervisor.scheduleIdleLocked();
6301            }
6302        }
6303
6304        return didSomething;
6305    }
6306
6307    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6308        ProcessRecord old = mProcessNames.remove(name, uid);
6309        if (old != null) {
6310            old.uidRecord.numProcs--;
6311            if (old.uidRecord.numProcs == 0) {
6312                // No more processes using this uid, tell clients it is gone.
6313                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6314                        "No more processes in " + old.uidRecord);
6315                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6316                mActiveUids.remove(uid);
6317                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6318            }
6319            old.uidRecord = null;
6320        }
6321        mIsolatedProcesses.remove(uid);
6322        return old;
6323    }
6324
6325    private final void addProcessNameLocked(ProcessRecord proc) {
6326        // We shouldn't already have a process under this name, but just in case we
6327        // need to clean up whatever may be there now.
6328        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6329        if (old == proc && proc.persistent) {
6330            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6331            Slog.w(TAG, "Re-adding persistent process " + proc);
6332        } else if (old != null) {
6333            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6334        }
6335        UidRecord uidRec = mActiveUids.get(proc.uid);
6336        if (uidRec == null) {
6337            uidRec = new UidRecord(proc.uid);
6338            // This is the first appearance of the uid, report it now!
6339            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6340                    "Creating new process uid: " + uidRec);
6341            mActiveUids.put(proc.uid, uidRec);
6342            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6343            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6344        }
6345        proc.uidRecord = uidRec;
6346
6347        // Reset render thread tid if it was already set, so new process can set it again.
6348        proc.renderThreadTid = 0;
6349        uidRec.numProcs++;
6350        mProcessNames.put(proc.processName, proc.uid, proc);
6351        if (proc.isolated) {
6352            mIsolatedProcesses.put(proc.uid, proc);
6353        }
6354    }
6355
6356    boolean removeProcessLocked(ProcessRecord app,
6357            boolean callerWillRestart, boolean allowRestart, String reason) {
6358        final String name = app.processName;
6359        final int uid = app.uid;
6360        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6361            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6362
6363        ProcessRecord old = mProcessNames.get(name, uid);
6364        if (old != app) {
6365            // This process is no longer active, so nothing to do.
6366            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6367            return false;
6368        }
6369        removeProcessNameLocked(name, uid);
6370        if (mHeavyWeightProcess == app) {
6371            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6372                    mHeavyWeightProcess.userId, 0));
6373            mHeavyWeightProcess = null;
6374        }
6375        boolean needRestart = false;
6376        if (app.pid > 0 && app.pid != MY_PID) {
6377            int pid = app.pid;
6378            synchronized (mPidsSelfLocked) {
6379                mPidsSelfLocked.remove(pid);
6380                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6381            }
6382            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6383            if (app.isolated) {
6384                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6385            }
6386            boolean willRestart = false;
6387            if (app.persistent && !app.isolated) {
6388                if (!callerWillRestart) {
6389                    willRestart = true;
6390                } else {
6391                    needRestart = true;
6392                }
6393            }
6394            app.kill(reason, true);
6395            handleAppDiedLocked(app, willRestart, allowRestart);
6396            if (willRestart) {
6397                removeLruProcessLocked(app);
6398                addAppLocked(app.info, false, null /* ABI override */);
6399            }
6400        } else {
6401            mRemovedProcesses.add(app);
6402        }
6403
6404        return needRestart;
6405    }
6406
6407    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6408        cleanupAppInLaunchingProvidersLocked(app, true);
6409        removeProcessLocked(app, false, true, "timeout publishing content providers");
6410    }
6411
6412    private final void processStartTimedOutLocked(ProcessRecord app) {
6413        final int pid = app.pid;
6414        boolean gone = false;
6415        synchronized (mPidsSelfLocked) {
6416            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6417            if (knownApp != null && knownApp.thread == null) {
6418                mPidsSelfLocked.remove(pid);
6419                gone = true;
6420            }
6421        }
6422
6423        if (gone) {
6424            Slog.w(TAG, "Process " + app + " failed to attach");
6425            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6426                    pid, app.uid, app.processName);
6427            removeProcessNameLocked(app.processName, app.uid);
6428            if (mHeavyWeightProcess == app) {
6429                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6430                        mHeavyWeightProcess.userId, 0));
6431                mHeavyWeightProcess = null;
6432            }
6433            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6434            if (app.isolated) {
6435                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6436            }
6437            // Take care of any launching providers waiting for this process.
6438            cleanupAppInLaunchingProvidersLocked(app, true);
6439            // Take care of any services that are waiting for the process.
6440            mServices.processStartTimedOutLocked(app);
6441            app.kill("start timeout", true);
6442            removeLruProcessLocked(app);
6443            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6444                Slog.w(TAG, "Unattached app died before backup, skipping");
6445                mHandler.post(new Runnable() {
6446                @Override
6447                    public void run(){
6448                        try {
6449                            IBackupManager bm = IBackupManager.Stub.asInterface(
6450                                    ServiceManager.getService(Context.BACKUP_SERVICE));
6451                            bm.agentDisconnected(app.info.packageName);
6452                        } catch (RemoteException e) {
6453                            // Can't happen; the backup manager is local
6454                        }
6455                    }
6456                });
6457            }
6458            if (isPendingBroadcastProcessLocked(pid)) {
6459                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6460                skipPendingBroadcastLocked(pid);
6461            }
6462        } else {
6463            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6464        }
6465    }
6466
6467    private final boolean attachApplicationLocked(IApplicationThread thread,
6468            int pid) {
6469
6470        // Find the application record that is being attached...  either via
6471        // the pid if we are running in multiple processes, or just pull the
6472        // next app record if we are emulating process with anonymous threads.
6473        ProcessRecord app;
6474        if (pid != MY_PID && pid >= 0) {
6475            synchronized (mPidsSelfLocked) {
6476                app = mPidsSelfLocked.get(pid);
6477            }
6478        } else {
6479            app = null;
6480        }
6481
6482        if (app == null) {
6483            Slog.w(TAG, "No pending application record for pid " + pid
6484                    + " (IApplicationThread " + thread + "); dropping process");
6485            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6486            if (pid > 0 && pid != MY_PID) {
6487                Process.killProcessQuiet(pid);
6488                //TODO: killProcessGroup(app.info.uid, pid);
6489            } else {
6490                try {
6491                    thread.scheduleExit();
6492                } catch (Exception e) {
6493                    // Ignore exceptions.
6494                }
6495            }
6496            return false;
6497        }
6498
6499        // If this application record is still attached to a previous
6500        // process, clean it up now.
6501        if (app.thread != null) {
6502            handleAppDiedLocked(app, true, true);
6503        }
6504
6505        // Tell the process all about itself.
6506
6507        if (DEBUG_ALL) Slog.v(
6508                TAG, "Binding process pid " + pid + " to record " + app);
6509
6510        final String processName = app.processName;
6511        try {
6512            AppDeathRecipient adr = new AppDeathRecipient(
6513                    app, pid, thread);
6514            thread.asBinder().linkToDeath(adr, 0);
6515            app.deathRecipient = adr;
6516        } catch (RemoteException e) {
6517            app.resetPackageList(mProcessStats);
6518            startProcessLocked(app, "link fail", processName);
6519            return false;
6520        }
6521
6522        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6523
6524        app.makeActive(thread, mProcessStats);
6525        app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6526        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6527        app.forcingToForeground = null;
6528        updateProcessForegroundLocked(app, false, false);
6529        app.hasShownUi = false;
6530        app.debugging = false;
6531        app.cached = false;
6532        app.killedByAm = false;
6533        app.killed = false;
6534
6535
6536        // We carefully use the same state that PackageManager uses for
6537        // filtering, since we use this flag to decide if we need to install
6538        // providers when user is unlocked later
6539        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6540
6541        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6542
6543        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6544        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6545
6546        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6547            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6548            msg.obj = app;
6549            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6550        }
6551
6552        if (!normalMode) {
6553            Slog.i(TAG, "Launching preboot mode app: " + app);
6554        }
6555
6556        if (DEBUG_ALL) Slog.v(
6557            TAG, "New app record " + app
6558            + " thread=" + thread.asBinder() + " pid=" + pid);
6559        try {
6560            int testMode = IApplicationThread.DEBUG_OFF;
6561            if (mDebugApp != null && mDebugApp.equals(processName)) {
6562                testMode = mWaitForDebugger
6563                    ? IApplicationThread.DEBUG_WAIT
6564                    : IApplicationThread.DEBUG_ON;
6565                app.debugging = true;
6566                if (mDebugTransient) {
6567                    mDebugApp = mOrigDebugApp;
6568                    mWaitForDebugger = mOrigWaitForDebugger;
6569                }
6570            }
6571            String profileFile = app.instrumentationProfileFile;
6572            ParcelFileDescriptor profileFd = null;
6573            int samplingInterval = 0;
6574            boolean profileAutoStop = false;
6575            if (mProfileApp != null && mProfileApp.equals(processName)) {
6576                mProfileProc = app;
6577                profileFile = mProfileFile;
6578                profileFd = mProfileFd;
6579                samplingInterval = mSamplingInterval;
6580                profileAutoStop = mAutoStopProfiler;
6581            }
6582            boolean enableTrackAllocation = false;
6583            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6584                enableTrackAllocation = true;
6585                mTrackAllocationApp = null;
6586            }
6587
6588            // If the app is being launched for restore or full backup, set it up specially
6589            boolean isRestrictedBackupMode = false;
6590            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6591                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6592                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6593                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6594                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6595            }
6596
6597            if (app.instrumentationClass != null) {
6598                notifyPackageUse(app.instrumentationClass.getPackageName(),
6599                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6600            }
6601            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6602                    + processName + " with config " + mConfiguration);
6603            ApplicationInfo appInfo = app.instrumentationInfo != null
6604                    ? app.instrumentationInfo : app.info;
6605            app.compat = compatibilityInfoForPackageLocked(appInfo);
6606            if (profileFd != null) {
6607                profileFd = profileFd.dup();
6608            }
6609            ProfilerInfo profilerInfo = profileFile == null ? null
6610                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6611            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6612                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6613                    app.instrumentationUiAutomationConnection, testMode,
6614                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6615                    isRestrictedBackupMode || !normalMode, app.persistent,
6616                    new Configuration(mConfiguration), app.compat,
6617                    getCommonServicesLocked(app.isolated),
6618                    mCoreSettingsObserver.getCoreSettingsLocked());
6619            updateLruProcessLocked(app, false, null);
6620            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6621        } catch (Exception e) {
6622            // todo: Yikes!  What should we do?  For now we will try to
6623            // start another process, but that could easily get us in
6624            // an infinite loop of restarting processes...
6625            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6626
6627            app.resetPackageList(mProcessStats);
6628            app.unlinkDeathRecipient();
6629            startProcessLocked(app, "bind fail", processName);
6630            return false;
6631        }
6632
6633        // Remove this record from the list of starting applications.
6634        mPersistentStartingProcesses.remove(app);
6635        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6636                "Attach application locked removing on hold: " + app);
6637        mProcessesOnHold.remove(app);
6638
6639        boolean badApp = false;
6640        boolean didSomething = false;
6641
6642        // See if the top visible activity is waiting to run in this process...
6643        if (normalMode) {
6644            try {
6645                if (mStackSupervisor.attachApplicationLocked(app)) {
6646                    didSomething = true;
6647                }
6648            } catch (Exception e) {
6649                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6650                badApp = true;
6651            }
6652        }
6653
6654        // Find any services that should be running in this process...
6655        if (!badApp) {
6656            try {
6657                didSomething |= mServices.attachApplicationLocked(app, processName);
6658            } catch (Exception e) {
6659                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6660                badApp = true;
6661            }
6662        }
6663
6664        // Check if a next-broadcast receiver is in this process...
6665        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6666            try {
6667                didSomething |= sendPendingBroadcastsLocked(app);
6668            } catch (Exception e) {
6669                // If the app died trying to launch the receiver we declare it 'bad'
6670                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6671                badApp = true;
6672            }
6673        }
6674
6675        // Check whether the next backup agent is in this process...
6676        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6677            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6678                    "New app is backup target, launching agent for " + app);
6679            notifyPackageUse(mBackupTarget.appInfo.packageName,
6680                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6681            try {
6682                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6683                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6684                        mBackupTarget.backupMode);
6685            } catch (Exception e) {
6686                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6687                badApp = true;
6688            }
6689        }
6690
6691        if (badApp) {
6692            app.kill("error during init", true);
6693            handleAppDiedLocked(app, false, true);
6694            return false;
6695        }
6696
6697        if (!didSomething) {
6698            updateOomAdjLocked();
6699        }
6700
6701        return true;
6702    }
6703
6704    @Override
6705    public final void attachApplication(IApplicationThread thread) {
6706        synchronized (this) {
6707            int callingPid = Binder.getCallingPid();
6708            final long origId = Binder.clearCallingIdentity();
6709            attachApplicationLocked(thread, callingPid);
6710            Binder.restoreCallingIdentity(origId);
6711        }
6712    }
6713
6714    @Override
6715    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6716        final long origId = Binder.clearCallingIdentity();
6717        synchronized (this) {
6718            ActivityStack stack = ActivityRecord.getStackLocked(token);
6719            if (stack != null) {
6720                ActivityRecord r =
6721                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6722                if (stopProfiling) {
6723                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6724                        try {
6725                            mProfileFd.close();
6726                        } catch (IOException e) {
6727                        }
6728                        clearProfilerLocked();
6729                    }
6730                }
6731            }
6732        }
6733        Binder.restoreCallingIdentity(origId);
6734    }
6735
6736    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6737        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6738                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6739    }
6740
6741    void enableScreenAfterBoot() {
6742        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6743                SystemClock.uptimeMillis());
6744        mWindowManager.enableScreenAfterBoot();
6745
6746        synchronized (this) {
6747            updateEventDispatchingLocked();
6748        }
6749    }
6750
6751    @Override
6752    public void showBootMessage(final CharSequence msg, final boolean always) {
6753        if (Binder.getCallingUid() != Process.myUid()) {
6754            throw new SecurityException();
6755        }
6756        mWindowManager.showBootMessage(msg, always);
6757    }
6758
6759    @Override
6760    public void keyguardWaitingForActivityDrawn() {
6761        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6762        final long token = Binder.clearCallingIdentity();
6763        try {
6764            synchronized (this) {
6765                if (DEBUG_LOCKSCREEN) logLockScreen("");
6766                mWindowManager.keyguardWaitingForActivityDrawn();
6767                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6768                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6769                    updateSleepIfNeededLocked();
6770                }
6771            }
6772        } finally {
6773            Binder.restoreCallingIdentity(token);
6774        }
6775    }
6776
6777    @Override
6778    public void keyguardGoingAway(int flags) {
6779        enforceNotIsolatedCaller("keyguardGoingAway");
6780        final long token = Binder.clearCallingIdentity();
6781        try {
6782            synchronized (this) {
6783                if (DEBUG_LOCKSCREEN) logLockScreen("");
6784                mWindowManager.keyguardGoingAway(flags);
6785                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6786                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6787                    updateSleepIfNeededLocked();
6788
6789                    // Some stack visibility might change (e.g. docked stack)
6790                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6791                    applyVrModeIfNeededLocked(mFocusedActivity, true);
6792                }
6793            }
6794        } finally {
6795            Binder.restoreCallingIdentity(token);
6796        }
6797    }
6798
6799    final void finishBooting() {
6800        synchronized (this) {
6801            if (!mBootAnimationComplete) {
6802                mCallFinishBooting = true;
6803                return;
6804            }
6805            mCallFinishBooting = false;
6806        }
6807
6808        ArraySet<String> completedIsas = new ArraySet<String>();
6809        for (String abi : Build.SUPPORTED_ABIS) {
6810            Process.zygoteProcess.establishZygoteConnectionForAbi(abi);
6811            final String instructionSet = VMRuntime.getInstructionSet(abi);
6812            if (!completedIsas.contains(instructionSet)) {
6813                try {
6814                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6815                } catch (InstallerException e) {
6816                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6817                            e.getMessage() +")");
6818                }
6819                completedIsas.add(instructionSet);
6820            }
6821        }
6822
6823        IntentFilter pkgFilter = new IntentFilter();
6824        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6825        pkgFilter.addDataScheme("package");
6826        mContext.registerReceiver(new BroadcastReceiver() {
6827            @Override
6828            public void onReceive(Context context, Intent intent) {
6829                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6830                if (pkgs != null) {
6831                    for (String pkg : pkgs) {
6832                        synchronized (ActivityManagerService.this) {
6833                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6834                                    0, "query restart")) {
6835                                setResultCode(Activity.RESULT_OK);
6836                                return;
6837                            }
6838                        }
6839                    }
6840                }
6841            }
6842        }, pkgFilter);
6843
6844        IntentFilter dumpheapFilter = new IntentFilter();
6845        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6846        mContext.registerReceiver(new BroadcastReceiver() {
6847            @Override
6848            public void onReceive(Context context, Intent intent) {
6849                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6850                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6851                } else {
6852                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6853                }
6854            }
6855        }, dumpheapFilter);
6856
6857        // Let system services know.
6858        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6859
6860        synchronized (this) {
6861            // Ensure that any processes we had put on hold are now started
6862            // up.
6863            final int NP = mProcessesOnHold.size();
6864            if (NP > 0) {
6865                ArrayList<ProcessRecord> procs =
6866                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6867                for (int ip=0; ip<NP; ip++) {
6868                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6869                            + procs.get(ip));
6870                    startProcessLocked(procs.get(ip), "on-hold", null);
6871                }
6872            }
6873
6874            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6875                // Start looking for apps that are abusing wake locks.
6876                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6877                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6878                // Tell anyone interested that we are done booting!
6879                SystemProperties.set("sys.boot_completed", "1");
6880
6881                // And trigger dev.bootcomplete if we are not showing encryption progress
6882                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6883                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6884                    SystemProperties.set("dev.bootcomplete", "1");
6885                }
6886                mUserController.sendBootCompletedLocked(
6887                        new IIntentReceiver.Stub() {
6888                            @Override
6889                            public void performReceive(Intent intent, int resultCode,
6890                                    String data, Bundle extras, boolean ordered,
6891                                    boolean sticky, int sendingUser) {
6892                                synchronized (ActivityManagerService.this) {
6893                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6894                                            true, false);
6895                                }
6896                            }
6897                        });
6898                scheduleStartProfilesLocked();
6899            }
6900        }
6901    }
6902
6903    @Override
6904    public void bootAnimationComplete() {
6905        final boolean callFinishBooting;
6906        synchronized (this) {
6907            callFinishBooting = mCallFinishBooting;
6908            mBootAnimationComplete = true;
6909        }
6910        if (callFinishBooting) {
6911            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6912            finishBooting();
6913            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6914        }
6915    }
6916
6917    final void ensureBootCompleted() {
6918        boolean booting;
6919        boolean enableScreen;
6920        synchronized (this) {
6921            booting = mBooting;
6922            mBooting = false;
6923            enableScreen = !mBooted;
6924            mBooted = true;
6925        }
6926
6927        if (booting) {
6928            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6929            finishBooting();
6930            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6931        }
6932
6933        if (enableScreen) {
6934            enableScreenAfterBoot();
6935        }
6936    }
6937
6938    @Override
6939    public final void activityResumed(IBinder token) {
6940        final long origId = Binder.clearCallingIdentity();
6941        synchronized(this) {
6942            ActivityStack stack = ActivityRecord.getStackLocked(token);
6943            if (stack != null) {
6944                stack.activityResumedLocked(token);
6945            }
6946        }
6947        Binder.restoreCallingIdentity(origId);
6948    }
6949
6950    @Override
6951    public final void activityPaused(IBinder token) {
6952        final long origId = Binder.clearCallingIdentity();
6953        synchronized(this) {
6954            ActivityStack stack = ActivityRecord.getStackLocked(token);
6955            if (stack != null) {
6956                stack.activityPausedLocked(token, false);
6957            }
6958        }
6959        Binder.restoreCallingIdentity(origId);
6960    }
6961
6962    @Override
6963    public final void activityStopped(IBinder token, Bundle icicle,
6964            PersistableBundle persistentState, CharSequence description) {
6965        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6966
6967        // Refuse possible leaked file descriptors
6968        if (icicle != null && icicle.hasFileDescriptors()) {
6969            throw new IllegalArgumentException("File descriptors passed in Bundle");
6970        }
6971
6972        final long origId = Binder.clearCallingIdentity();
6973
6974        synchronized (this) {
6975            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6976            if (r != null) {
6977                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6978            }
6979        }
6980
6981        trimApplications();
6982
6983        Binder.restoreCallingIdentity(origId);
6984    }
6985
6986    @Override
6987    public final void activityDestroyed(IBinder token) {
6988        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6989        synchronized (this) {
6990            ActivityStack stack = ActivityRecord.getStackLocked(token);
6991            if (stack != null) {
6992                stack.activityDestroyedLocked(token, "activityDestroyed");
6993            }
6994        }
6995    }
6996
6997    @Override
6998    public final void activityRelaunched(IBinder token) {
6999        final long origId = Binder.clearCallingIdentity();
7000        synchronized (this) {
7001            mStackSupervisor.activityRelaunchedLocked(token);
7002        }
7003        Binder.restoreCallingIdentity(origId);
7004    }
7005
7006    @Override
7007    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
7008            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
7009        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
7010                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
7011        synchronized (this) {
7012            ActivityRecord record = ActivityRecord.isInStackLocked(token);
7013            if (record == null) {
7014                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
7015                        + "found for: " + token);
7016            }
7017            record.setSizeConfigurations(horizontalSizeConfiguration,
7018                    verticalSizeConfigurations, smallestSizeConfigurations);
7019        }
7020    }
7021
7022    @Override
7023    public final void backgroundResourcesReleased(IBinder token) {
7024        final long origId = Binder.clearCallingIdentity();
7025        try {
7026            synchronized (this) {
7027                ActivityStack stack = ActivityRecord.getStackLocked(token);
7028                if (stack != null) {
7029                    stack.backgroundResourcesReleased();
7030                }
7031            }
7032        } finally {
7033            Binder.restoreCallingIdentity(origId);
7034        }
7035    }
7036
7037    @Override
7038    public final void notifyLaunchTaskBehindComplete(IBinder token) {
7039        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
7040    }
7041
7042    @Override
7043    public final void notifyEnterAnimationComplete(IBinder token) {
7044        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
7045    }
7046
7047    @Override
7048    public String getCallingPackage(IBinder token) {
7049        synchronized (this) {
7050            ActivityRecord r = getCallingRecordLocked(token);
7051            return r != null ? r.info.packageName : null;
7052        }
7053    }
7054
7055    @Override
7056    public ComponentName getCallingActivity(IBinder token) {
7057        synchronized (this) {
7058            ActivityRecord r = getCallingRecordLocked(token);
7059            return r != null ? r.intent.getComponent() : null;
7060        }
7061    }
7062
7063    private ActivityRecord getCallingRecordLocked(IBinder token) {
7064        ActivityRecord r = ActivityRecord.isInStackLocked(token);
7065        if (r == null) {
7066            return null;
7067        }
7068        return r.resultTo;
7069    }
7070
7071    @Override
7072    public ComponentName getActivityClassForToken(IBinder token) {
7073        synchronized(this) {
7074            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7075            if (r == null) {
7076                return null;
7077            }
7078            return r.intent.getComponent();
7079        }
7080    }
7081
7082    @Override
7083    public String getPackageForToken(IBinder token) {
7084        synchronized(this) {
7085            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7086            if (r == null) {
7087                return null;
7088            }
7089            return r.packageName;
7090        }
7091    }
7092
7093    @Override
7094    public boolean isRootVoiceInteraction(IBinder token) {
7095        synchronized(this) {
7096            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7097            if (r == null) {
7098                return false;
7099            }
7100            return r.rootVoiceInteraction;
7101        }
7102    }
7103
7104    @Override
7105    public IIntentSender getIntentSender(int type,
7106            String packageName, IBinder token, String resultWho,
7107            int requestCode, Intent[] intents, String[] resolvedTypes,
7108            int flags, Bundle bOptions, int userId) {
7109        enforceNotIsolatedCaller("getIntentSender");
7110        // Refuse possible leaked file descriptors
7111        if (intents != null) {
7112            if (intents.length < 1) {
7113                throw new IllegalArgumentException("Intents array length must be >= 1");
7114            }
7115            for (int i=0; i<intents.length; i++) {
7116                Intent intent = intents[i];
7117                if (intent != null) {
7118                    if (intent.hasFileDescriptors()) {
7119                        throw new IllegalArgumentException("File descriptors passed in Intent");
7120                    }
7121                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7122                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7123                        throw new IllegalArgumentException(
7124                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7125                    }
7126                    intents[i] = new Intent(intent);
7127                }
7128            }
7129            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7130                throw new IllegalArgumentException(
7131                        "Intent array length does not match resolvedTypes length");
7132            }
7133        }
7134        if (bOptions != null) {
7135            if (bOptions.hasFileDescriptors()) {
7136                throw new IllegalArgumentException("File descriptors passed in options");
7137            }
7138        }
7139
7140        synchronized(this) {
7141            int callingUid = Binder.getCallingUid();
7142            int origUserId = userId;
7143            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7144                    type == ActivityManager.INTENT_SENDER_BROADCAST,
7145                    ALLOW_NON_FULL, "getIntentSender", null);
7146            if (origUserId == UserHandle.USER_CURRENT) {
7147                // We don't want to evaluate this until the pending intent is
7148                // actually executed.  However, we do want to always do the
7149                // security checking for it above.
7150                userId = UserHandle.USER_CURRENT;
7151            }
7152            try {
7153                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
7154                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7155                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7156                    if (!UserHandle.isSameApp(callingUid, uid)) {
7157                        String msg = "Permission Denial: getIntentSender() from pid="
7158                            + Binder.getCallingPid()
7159                            + ", uid=" + Binder.getCallingUid()
7160                            + ", (need uid=" + uid + ")"
7161                            + " is not allowed to send as package " + packageName;
7162                        Slog.w(TAG, msg);
7163                        throw new SecurityException(msg);
7164                    }
7165                }
7166
7167                return getIntentSenderLocked(type, packageName, callingUid, userId,
7168                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7169
7170            } catch (RemoteException e) {
7171                throw new SecurityException(e);
7172            }
7173        }
7174    }
7175
7176    IIntentSender getIntentSenderLocked(int type, String packageName,
7177            int callingUid, int userId, IBinder token, String resultWho,
7178            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7179            Bundle bOptions) {
7180        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7181        ActivityRecord activity = null;
7182        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7183            activity = ActivityRecord.isInStackLocked(token);
7184            if (activity == null) {
7185                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7186                return null;
7187            }
7188            if (activity.finishing) {
7189                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7190                return null;
7191            }
7192        }
7193
7194        // We're going to be splicing together extras before sending, so we're
7195        // okay poking into any contained extras.
7196        if (intents != null) {
7197            for (int i = 0; i < intents.length; i++) {
7198                intents[i].setDefusable(true);
7199            }
7200        }
7201        Bundle.setDefusable(bOptions, true);
7202
7203        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7204        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7205        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7206        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7207                |PendingIntent.FLAG_UPDATE_CURRENT);
7208
7209        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7210                type, packageName, activity, resultWho,
7211                requestCode, intents, resolvedTypes, flags, bOptions, userId);
7212        WeakReference<PendingIntentRecord> ref;
7213        ref = mIntentSenderRecords.get(key);
7214        PendingIntentRecord rec = ref != null ? ref.get() : null;
7215        if (rec != null) {
7216            if (!cancelCurrent) {
7217                if (updateCurrent) {
7218                    if (rec.key.requestIntent != null) {
7219                        rec.key.requestIntent.replaceExtras(intents != null ?
7220                                intents[intents.length - 1] : null);
7221                    }
7222                    if (intents != null) {
7223                        intents[intents.length-1] = rec.key.requestIntent;
7224                        rec.key.allIntents = intents;
7225                        rec.key.allResolvedTypes = resolvedTypes;
7226                    } else {
7227                        rec.key.allIntents = null;
7228                        rec.key.allResolvedTypes = null;
7229                    }
7230                }
7231                return rec;
7232            }
7233            rec.canceled = true;
7234            mIntentSenderRecords.remove(key);
7235        }
7236        if (noCreate) {
7237            return rec;
7238        }
7239        rec = new PendingIntentRecord(this, key, callingUid);
7240        mIntentSenderRecords.put(key, rec.ref);
7241        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7242            if (activity.pendingResults == null) {
7243                activity.pendingResults
7244                        = new HashSet<WeakReference<PendingIntentRecord>>();
7245            }
7246            activity.pendingResults.add(rec.ref);
7247        }
7248        return rec;
7249    }
7250
7251    @Override
7252    public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7253            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7254        if (target instanceof PendingIntentRecord) {
7255            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7256                    finishedReceiver, requiredPermission, options);
7257        } else {
7258            if (intent == null) {
7259                // Weird case: someone has given us their own custom IIntentSender, and now
7260                // they have someone else trying to send to it but of course this isn't
7261                // really a PendingIntent, so there is no base Intent, and the caller isn't
7262                // supplying an Intent... but we never want to dispatch a null Intent to
7263                // a receiver, so um...  let's make something up.
7264                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7265                intent = new Intent(Intent.ACTION_MAIN);
7266            }
7267            try {
7268                target.send(code, intent, resolvedType, null, requiredPermission, options);
7269            } catch (RemoteException e) {
7270            }
7271            // Platform code can rely on getting a result back when the send is done, but if
7272            // this intent sender is from outside of the system we can't rely on it doing that.
7273            // So instead we don't give it the result receiver, and instead just directly
7274            // report the finish immediately.
7275            if (finishedReceiver != null) {
7276                try {
7277                    finishedReceiver.performReceive(intent, 0,
7278                            null, null, false, false, UserHandle.getCallingUserId());
7279                } catch (RemoteException e) {
7280                }
7281            }
7282            return 0;
7283        }
7284    }
7285
7286    /**
7287     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
7288     *
7289     * <p>{@code callerUid} must be allowed to request such whitelist by calling
7290     * {@link #addTempPowerSaveWhitelistGrantorUid(int)}.
7291     */
7292    void tempWhitelistAppForPowerSave(int callerPid, int callerUid, int targetUid, long duration) {
7293        if (DEBUG_WHITELISTS) {
7294            Slog.d(TAG, "tempWhitelistAppForPowerSave(" + callerPid + ", " + callerUid + ", "
7295                    + targetUid + ", " + duration + ")");
7296        }
7297        synchronized (mPidsSelfLocked) {
7298            final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
7299            if (pr == null) {
7300                Slog.w(TAG, "tempWhitelistAppForPowerSave() no ProcessRecord for pid " + callerPid);
7301                return;
7302            }
7303            if (!pr.whitelistManager) {
7304                if (DEBUG_WHITELISTS) {
7305                    Slog.d(TAG, "tempWhitelistAppForPowerSave() for target " + targetUid + ": pid "
7306                            + callerPid + " is not allowed");
7307                }
7308                return;
7309            }
7310        }
7311
7312        final long token = Binder.clearCallingIdentity();
7313        try {
7314            mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(targetUid, duration,
7315                    true, "pe from uid:" + callerUid);
7316        } finally {
7317            Binder.restoreCallingIdentity(token);
7318        }
7319    }
7320
7321    @Override
7322    public void cancelIntentSender(IIntentSender sender) {
7323        if (!(sender instanceof PendingIntentRecord)) {
7324            return;
7325        }
7326        synchronized(this) {
7327            PendingIntentRecord rec = (PendingIntentRecord)sender;
7328            try {
7329                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7330                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7331                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7332                    String msg = "Permission Denial: cancelIntentSender() from pid="
7333                        + Binder.getCallingPid()
7334                        + ", uid=" + Binder.getCallingUid()
7335                        + " is not allowed to cancel packges "
7336                        + rec.key.packageName;
7337                    Slog.w(TAG, msg);
7338                    throw new SecurityException(msg);
7339                }
7340            } catch (RemoteException e) {
7341                throw new SecurityException(e);
7342            }
7343            cancelIntentSenderLocked(rec, true);
7344        }
7345    }
7346
7347    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7348        rec.canceled = true;
7349        mIntentSenderRecords.remove(rec.key);
7350        if (cleanActivity && rec.key.activity != null) {
7351            rec.key.activity.pendingResults.remove(rec.ref);
7352        }
7353    }
7354
7355    @Override
7356    public String getPackageForIntentSender(IIntentSender pendingResult) {
7357        if (!(pendingResult instanceof PendingIntentRecord)) {
7358            return null;
7359        }
7360        try {
7361            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7362            return res.key.packageName;
7363        } catch (ClassCastException e) {
7364        }
7365        return null;
7366    }
7367
7368    @Override
7369    public int getUidForIntentSender(IIntentSender sender) {
7370        if (sender instanceof PendingIntentRecord) {
7371            try {
7372                PendingIntentRecord res = (PendingIntentRecord)sender;
7373                return res.uid;
7374            } catch (ClassCastException e) {
7375            }
7376        }
7377        return -1;
7378    }
7379
7380    @Override
7381    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7382        if (!(pendingResult instanceof PendingIntentRecord)) {
7383            return false;
7384        }
7385        try {
7386            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7387            if (res.key.allIntents == null) {
7388                return false;
7389            }
7390            for (int i=0; i<res.key.allIntents.length; i++) {
7391                Intent intent = res.key.allIntents[i];
7392                if (intent.getPackage() != null && intent.getComponent() != null) {
7393                    return false;
7394                }
7395            }
7396            return true;
7397        } catch (ClassCastException e) {
7398        }
7399        return false;
7400    }
7401
7402    @Override
7403    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7404        if (!(pendingResult instanceof PendingIntentRecord)) {
7405            return false;
7406        }
7407        try {
7408            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7409            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7410                return true;
7411            }
7412            return false;
7413        } catch (ClassCastException e) {
7414        }
7415        return false;
7416    }
7417
7418    @Override
7419    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7420        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7421                "getIntentForIntentSender()");
7422        if (!(pendingResult instanceof PendingIntentRecord)) {
7423            return null;
7424        }
7425        try {
7426            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7427            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7428        } catch (ClassCastException e) {
7429        }
7430        return null;
7431    }
7432
7433    @Override
7434    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7435        if (!(pendingResult instanceof PendingIntentRecord)) {
7436            return null;
7437        }
7438        try {
7439            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7440            synchronized (this) {
7441                return getTagForIntentSenderLocked(res, prefix);
7442            }
7443        } catch (ClassCastException e) {
7444        }
7445        return null;
7446    }
7447
7448    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7449        final Intent intent = res.key.requestIntent;
7450        if (intent != null) {
7451            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7452                    || res.lastTagPrefix.equals(prefix))) {
7453                return res.lastTag;
7454            }
7455            res.lastTagPrefix = prefix;
7456            final StringBuilder sb = new StringBuilder(128);
7457            if (prefix != null) {
7458                sb.append(prefix);
7459            }
7460            if (intent.getAction() != null) {
7461                sb.append(intent.getAction());
7462            } else if (intent.getComponent() != null) {
7463                intent.getComponent().appendShortString(sb);
7464            } else {
7465                sb.append("?");
7466            }
7467            return res.lastTag = sb.toString();
7468        }
7469        return null;
7470    }
7471
7472    @Override
7473    public void setProcessLimit(int max) {
7474        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7475                "setProcessLimit()");
7476        synchronized (this) {
7477            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7478            mProcessLimitOverride = max;
7479        }
7480        trimApplications();
7481    }
7482
7483    @Override
7484    public int getProcessLimit() {
7485        synchronized (this) {
7486            return mProcessLimitOverride;
7487        }
7488    }
7489
7490    void foregroundTokenDied(ForegroundToken token) {
7491        synchronized (ActivityManagerService.this) {
7492            synchronized (mPidsSelfLocked) {
7493                ForegroundToken cur
7494                    = mForegroundProcesses.get(token.pid);
7495                if (cur != token) {
7496                    return;
7497                }
7498                mForegroundProcesses.remove(token.pid);
7499                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7500                if (pr == null) {
7501                    return;
7502                }
7503                pr.forcingToForeground = null;
7504                updateProcessForegroundLocked(pr, false, false);
7505            }
7506            updateOomAdjLocked();
7507        }
7508    }
7509
7510    @Override
7511    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7512        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7513                "setProcessForeground()");
7514        synchronized(this) {
7515            boolean changed = false;
7516
7517            synchronized (mPidsSelfLocked) {
7518                ProcessRecord pr = mPidsSelfLocked.get(pid);
7519                if (pr == null && isForeground) {
7520                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7521                    return;
7522                }
7523                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7524                if (oldToken != null) {
7525                    oldToken.token.unlinkToDeath(oldToken, 0);
7526                    mForegroundProcesses.remove(pid);
7527                    if (pr != null) {
7528                        pr.forcingToForeground = null;
7529                    }
7530                    changed = true;
7531                }
7532                if (isForeground && token != null) {
7533                    ForegroundToken newToken = new ForegroundToken() {
7534                        @Override
7535                        public void binderDied() {
7536                            foregroundTokenDied(this);
7537                        }
7538                    };
7539                    newToken.pid = pid;
7540                    newToken.token = token;
7541                    try {
7542                        token.linkToDeath(newToken, 0);
7543                        mForegroundProcesses.put(pid, newToken);
7544                        pr.forcingToForeground = token;
7545                        changed = true;
7546                    } catch (RemoteException e) {
7547                        // If the process died while doing this, we will later
7548                        // do the cleanup with the process death link.
7549                    }
7550                }
7551            }
7552
7553            if (changed) {
7554                updateOomAdjLocked();
7555            }
7556        }
7557    }
7558
7559    @Override
7560    public boolean isAppForeground(int uid) throws RemoteException {
7561        synchronized (this) {
7562            UidRecord uidRec = mActiveUids.get(uid);
7563            if (uidRec == null || uidRec.idle) {
7564                return false;
7565            }
7566            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7567        }
7568    }
7569
7570    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7571    // be guarded by permission checking.
7572    int getUidState(int uid) {
7573        synchronized (this) {
7574            UidRecord uidRec = mActiveUids.get(uid);
7575            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7576        }
7577    }
7578
7579    @Override
7580    public boolean isInMultiWindowMode(IBinder token) {
7581        final long origId = Binder.clearCallingIdentity();
7582        try {
7583            synchronized(this) {
7584                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7585                if (r == null) {
7586                    return false;
7587                }
7588                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7589                return !r.task.mFullscreen;
7590            }
7591        } finally {
7592            Binder.restoreCallingIdentity(origId);
7593        }
7594    }
7595
7596    @Override
7597    public boolean isInPictureInPictureMode(IBinder token) {
7598        final long origId = Binder.clearCallingIdentity();
7599        try {
7600            synchronized(this) {
7601                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7602                if (stack == null) {
7603                    return false;
7604                }
7605                return stack.mStackId == PINNED_STACK_ID;
7606            }
7607        } finally {
7608            Binder.restoreCallingIdentity(origId);
7609        }
7610    }
7611
7612    @Override
7613    public void enterPictureInPictureMode(IBinder token) {
7614        final long origId = Binder.clearCallingIdentity();
7615        try {
7616            synchronized(this) {
7617                if (!mSupportsPictureInPicture) {
7618                    throw new IllegalStateException("enterPictureInPictureMode: "
7619                            + "Device doesn't support picture-in-picture mode.");
7620                }
7621
7622                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7623
7624                if (r == null) {
7625                    throw new IllegalStateException("enterPictureInPictureMode: "
7626                            + "Can't find activity for token=" + token);
7627                }
7628
7629                if (!r.supportsPictureInPicture()) {
7630                    throw new IllegalArgumentException("enterPictureInPictureMode: "
7631                            + "Picture-In-Picture not supported for r=" + r);
7632                }
7633
7634                // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
7635                // current bounds.
7636                final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
7637                final Rect bounds = (pinnedStack != null)
7638                        ? pinnedStack.mBounds : mDefaultPinnedStackBounds;
7639
7640                mStackSupervisor.moveActivityToPinnedStackLocked(
7641                        r, "enterPictureInPictureMode", bounds);
7642            }
7643        } finally {
7644            Binder.restoreCallingIdentity(origId);
7645        }
7646    }
7647
7648    // =========================================================
7649    // PROCESS INFO
7650    // =========================================================
7651
7652    static class ProcessInfoService extends IProcessInfoService.Stub {
7653        final ActivityManagerService mActivityManagerService;
7654        ProcessInfoService(ActivityManagerService activityManagerService) {
7655            mActivityManagerService = activityManagerService;
7656        }
7657
7658        @Override
7659        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7660            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7661                    /*in*/ pids, /*out*/ states, null);
7662        }
7663
7664        @Override
7665        public void getProcessStatesAndOomScoresFromPids(
7666                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7667            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7668                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7669        }
7670    }
7671
7672    /**
7673     * For each PID in the given input array, write the current process state
7674     * for that process into the states array, or -1 to indicate that no
7675     * process with the given PID exists. If scores array is provided, write
7676     * the oom score for the process into the scores array, with INVALID_ADJ
7677     * indicating the PID doesn't exist.
7678     */
7679    public void getProcessStatesAndOomScoresForPIDs(
7680            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7681        if (scores != null) {
7682            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7683                    "getProcessStatesAndOomScoresForPIDs()");
7684        }
7685
7686        if (pids == null) {
7687            throw new NullPointerException("pids");
7688        } else if (states == null) {
7689            throw new NullPointerException("states");
7690        } else if (pids.length != states.length) {
7691            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7692        } else if (scores != null && pids.length != scores.length) {
7693            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7694        }
7695
7696        synchronized (mPidsSelfLocked) {
7697            for (int i = 0; i < pids.length; i++) {
7698                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7699                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7700                        pr.curProcState;
7701                if (scores != null) {
7702                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7703                }
7704            }
7705        }
7706    }
7707
7708    // =========================================================
7709    // PERMISSIONS
7710    // =========================================================
7711
7712    static class PermissionController extends IPermissionController.Stub {
7713        ActivityManagerService mActivityManagerService;
7714        PermissionController(ActivityManagerService activityManagerService) {
7715            mActivityManagerService = activityManagerService;
7716        }
7717
7718        @Override
7719        public boolean checkPermission(String permission, int pid, int uid) {
7720            return mActivityManagerService.checkPermission(permission, pid,
7721                    uid) == PackageManager.PERMISSION_GRANTED;
7722        }
7723
7724        @Override
7725        public String[] getPackagesForUid(int uid) {
7726            return mActivityManagerService.mContext.getPackageManager()
7727                    .getPackagesForUid(uid);
7728        }
7729
7730        @Override
7731        public boolean isRuntimePermission(String permission) {
7732            try {
7733                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7734                        .getPermissionInfo(permission, 0);
7735                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7736            } catch (NameNotFoundException nnfe) {
7737                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7738            }
7739            return false;
7740        }
7741    }
7742
7743    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7744        @Override
7745        public int checkComponentPermission(String permission, int pid, int uid,
7746                int owningUid, boolean exported) {
7747            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7748                    owningUid, exported);
7749        }
7750
7751        @Override
7752        public Object getAMSLock() {
7753            return ActivityManagerService.this;
7754        }
7755    }
7756
7757    /**
7758     * This can be called with or without the global lock held.
7759     */
7760    int checkComponentPermission(String permission, int pid, int uid,
7761            int owningUid, boolean exported) {
7762        if (pid == MY_PID) {
7763            return PackageManager.PERMISSION_GRANTED;
7764        }
7765        return ActivityManager.checkComponentPermission(permission, uid,
7766                owningUid, exported);
7767    }
7768
7769    /**
7770     * As the only public entry point for permissions checking, this method
7771     * can enforce the semantic that requesting a check on a null global
7772     * permission is automatically denied.  (Internally a null permission
7773     * string is used when calling {@link #checkComponentPermission} in cases
7774     * when only uid-based security is needed.)
7775     *
7776     * This can be called with or without the global lock held.
7777     */
7778    @Override
7779    public int checkPermission(String permission, int pid, int uid) {
7780        if (permission == null) {
7781            return PackageManager.PERMISSION_DENIED;
7782        }
7783        return checkComponentPermission(permission, pid, uid, -1, true);
7784    }
7785
7786    @Override
7787    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7788        if (permission == null) {
7789            return PackageManager.PERMISSION_DENIED;
7790        }
7791
7792        // We might be performing an operation on behalf of an indirect binder
7793        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7794        // client identity accordingly before proceeding.
7795        Identity tlsIdentity = sCallerIdentity.get();
7796        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7797            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7798                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7799            uid = tlsIdentity.uid;
7800            pid = tlsIdentity.pid;
7801        }
7802
7803        return checkComponentPermission(permission, pid, uid, -1, true);
7804    }
7805
7806    /**
7807     * Binder IPC calls go through the public entry point.
7808     * This can be called with or without the global lock held.
7809     */
7810    int checkCallingPermission(String permission) {
7811        return checkPermission(permission,
7812                Binder.getCallingPid(),
7813                UserHandle.getAppId(Binder.getCallingUid()));
7814    }
7815
7816    /**
7817     * This can be called with or without the global lock held.
7818     */
7819    void enforceCallingPermission(String permission, String func) {
7820        if (checkCallingPermission(permission)
7821                == PackageManager.PERMISSION_GRANTED) {
7822            return;
7823        }
7824
7825        String msg = "Permission Denial: " + func + " from pid="
7826                + Binder.getCallingPid()
7827                + ", uid=" + Binder.getCallingUid()
7828                + " requires " + permission;
7829        Slog.w(TAG, msg);
7830        throw new SecurityException(msg);
7831    }
7832
7833    /**
7834     * Determine if UID is holding permissions required to access {@link Uri} in
7835     * the given {@link ProviderInfo}. Final permission checking is always done
7836     * in {@link ContentProvider}.
7837     */
7838    private final boolean checkHoldingPermissionsLocked(
7839            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7840        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7841                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7842        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7843            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7844                    != PERMISSION_GRANTED) {
7845                return false;
7846            }
7847        }
7848        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7849    }
7850
7851    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7852            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7853        if (pi.applicationInfo.uid == uid) {
7854            return true;
7855        } else if (!pi.exported) {
7856            return false;
7857        }
7858
7859        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7860        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7861        try {
7862            // check if target holds top-level <provider> permissions
7863            if (!readMet && pi.readPermission != null && considerUidPermissions
7864                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7865                readMet = true;
7866            }
7867            if (!writeMet && pi.writePermission != null && considerUidPermissions
7868                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7869                writeMet = true;
7870            }
7871
7872            // track if unprotected read/write is allowed; any denied
7873            // <path-permission> below removes this ability
7874            boolean allowDefaultRead = pi.readPermission == null;
7875            boolean allowDefaultWrite = pi.writePermission == null;
7876
7877            // check if target holds any <path-permission> that match uri
7878            final PathPermission[] pps = pi.pathPermissions;
7879            if (pps != null) {
7880                final String path = grantUri.uri.getPath();
7881                int i = pps.length;
7882                while (i > 0 && (!readMet || !writeMet)) {
7883                    i--;
7884                    PathPermission pp = pps[i];
7885                    if (pp.match(path)) {
7886                        if (!readMet) {
7887                            final String pprperm = pp.getReadPermission();
7888                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7889                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7890                                    + ": match=" + pp.match(path)
7891                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7892                            if (pprperm != null) {
7893                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7894                                        == PERMISSION_GRANTED) {
7895                                    readMet = true;
7896                                } else {
7897                                    allowDefaultRead = false;
7898                                }
7899                            }
7900                        }
7901                        if (!writeMet) {
7902                            final String ppwperm = pp.getWritePermission();
7903                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7904                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7905                                    + ": match=" + pp.match(path)
7906                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7907                            if (ppwperm != null) {
7908                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7909                                        == PERMISSION_GRANTED) {
7910                                    writeMet = true;
7911                                } else {
7912                                    allowDefaultWrite = false;
7913                                }
7914                            }
7915                        }
7916                    }
7917                }
7918            }
7919
7920            // grant unprotected <provider> read/write, if not blocked by
7921            // <path-permission> above
7922            if (allowDefaultRead) readMet = true;
7923            if (allowDefaultWrite) writeMet = true;
7924
7925        } catch (RemoteException e) {
7926            return false;
7927        }
7928
7929        return readMet && writeMet;
7930    }
7931
7932    public int getAppStartMode(int uid, String packageName) {
7933        synchronized (this) {
7934            return checkAllowBackgroundLocked(uid, packageName, -1, true);
7935        }
7936    }
7937
7938    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7939            boolean allowWhenForeground) {
7940        UidRecord uidRec = mActiveUids.get(uid);
7941        if (!mLenientBackgroundCheck) {
7942            if (!allowWhenForeground || uidRec == null
7943                    || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7944                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7945                        packageName) != AppOpsManager.MODE_ALLOWED) {
7946                    return ActivityManager.APP_START_MODE_DELAYED;
7947                }
7948            }
7949
7950        } else if (uidRec == null || uidRec.idle) {
7951            if (callingPid >= 0) {
7952                ProcessRecord proc;
7953                synchronized (mPidsSelfLocked) {
7954                    proc = mPidsSelfLocked.get(callingPid);
7955                }
7956                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7957                    // Whoever is instigating this is in the foreground, so we will allow it
7958                    // to go through.
7959                    return ActivityManager.APP_START_MODE_NORMAL;
7960                }
7961            }
7962            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7963                    != AppOpsManager.MODE_ALLOWED) {
7964                return ActivityManager.APP_START_MODE_DELAYED;
7965            }
7966        }
7967        return ActivityManager.APP_START_MODE_NORMAL;
7968    }
7969
7970    private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
7971        ProviderInfo pi = null;
7972        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7973        if (cpr != null) {
7974            pi = cpr.info;
7975        } else {
7976            try {
7977                pi = AppGlobals.getPackageManager().resolveContentProvider(
7978                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
7979                        userHandle);
7980            } catch (RemoteException ex) {
7981            }
7982        }
7983        return pi;
7984    }
7985
7986    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7987        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7988        if (targetUris != null) {
7989            return targetUris.get(grantUri);
7990        }
7991        return null;
7992    }
7993
7994    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7995            String targetPkg, int targetUid, GrantUri grantUri) {
7996        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7997        if (targetUris == null) {
7998            targetUris = Maps.newArrayMap();
7999            mGrantedUriPermissions.put(targetUid, targetUris);
8000        }
8001
8002        UriPermission perm = targetUris.get(grantUri);
8003        if (perm == null) {
8004            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
8005            targetUris.put(grantUri, perm);
8006        }
8007
8008        return perm;
8009    }
8010
8011    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
8012            final int modeFlags) {
8013        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
8014        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
8015                : UriPermission.STRENGTH_OWNED;
8016
8017        // Root gets to do everything.
8018        if (uid == 0) {
8019            return true;
8020        }
8021
8022        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8023        if (perms == null) return false;
8024
8025        // First look for exact match
8026        final UriPermission exactPerm = perms.get(grantUri);
8027        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
8028            return true;
8029        }
8030
8031        // No exact match, look for prefixes
8032        final int N = perms.size();
8033        for (int i = 0; i < N; i++) {
8034            final UriPermission perm = perms.valueAt(i);
8035            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
8036                    && perm.getStrength(modeFlags) >= minStrength) {
8037                return true;
8038            }
8039        }
8040
8041        return false;
8042    }
8043
8044    /**
8045     * @param uri This uri must NOT contain an embedded userId.
8046     * @param userId The userId in which the uri is to be resolved.
8047     */
8048    @Override
8049    public int checkUriPermission(Uri uri, int pid, int uid,
8050            final int modeFlags, int userId, IBinder callerToken) {
8051        enforceNotIsolatedCaller("checkUriPermission");
8052
8053        // Another redirected-binder-call permissions check as in
8054        // {@link checkPermissionWithToken}.
8055        Identity tlsIdentity = sCallerIdentity.get();
8056        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8057            uid = tlsIdentity.uid;
8058            pid = tlsIdentity.pid;
8059        }
8060
8061        // Our own process gets to do everything.
8062        if (pid == MY_PID) {
8063            return PackageManager.PERMISSION_GRANTED;
8064        }
8065        synchronized (this) {
8066            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
8067                    ? PackageManager.PERMISSION_GRANTED
8068                    : PackageManager.PERMISSION_DENIED;
8069        }
8070    }
8071
8072    /**
8073     * Check if the targetPkg can be granted permission to access uri by
8074     * the callingUid using the given modeFlags.  Throws a security exception
8075     * if callingUid is not allowed to do this.  Returns the uid of the target
8076     * if the URI permission grant should be performed; returns -1 if it is not
8077     * needed (for example targetPkg already has permission to access the URI).
8078     * If you already know the uid of the target, you can supply it in
8079     * lastTargetUid else set that to -1.
8080     */
8081    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8082            final int modeFlags, int lastTargetUid) {
8083        if (!Intent.isAccessUriMode(modeFlags)) {
8084            return -1;
8085        }
8086
8087        if (targetPkg != null) {
8088            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8089                    "Checking grant " + targetPkg + " permission to " + grantUri);
8090        }
8091
8092        final IPackageManager pm = AppGlobals.getPackageManager();
8093
8094        // If this is not a content: uri, we can't do anything with it.
8095        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8096            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8097                    "Can't grant URI permission for non-content URI: " + grantUri);
8098            return -1;
8099        }
8100
8101        final String authority = grantUri.uri.getAuthority();
8102        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8103                MATCH_DEBUG_TRIAGED_MISSING);
8104        if (pi == null) {
8105            Slog.w(TAG, "No content provider found for permission check: " +
8106                    grantUri.uri.toSafeString());
8107            return -1;
8108        }
8109
8110        int targetUid = lastTargetUid;
8111        if (targetUid < 0 && targetPkg != null) {
8112            try {
8113                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8114                        UserHandle.getUserId(callingUid));
8115                if (targetUid < 0) {
8116                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8117                            "Can't grant URI permission no uid for: " + targetPkg);
8118                    return -1;
8119                }
8120            } catch (RemoteException ex) {
8121                return -1;
8122            }
8123        }
8124
8125        if (targetUid >= 0) {
8126            // First...  does the target actually need this permission?
8127            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8128                // No need to grant the target this permission.
8129                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8130                        "Target " + targetPkg + " already has full permission to " + grantUri);
8131                return -1;
8132            }
8133        } else {
8134            // First...  there is no target package, so can anyone access it?
8135            boolean allowed = pi.exported;
8136            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8137                if (pi.readPermission != null) {
8138                    allowed = false;
8139                }
8140            }
8141            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8142                if (pi.writePermission != null) {
8143                    allowed = false;
8144                }
8145            }
8146            if (allowed) {
8147                return -1;
8148            }
8149        }
8150
8151        /* There is a special cross user grant if:
8152         * - The target is on another user.
8153         * - Apps on the current user can access the uri without any uid permissions.
8154         * In this case, we grant a uri permission, even if the ContentProvider does not normally
8155         * grant uri permissions.
8156         */
8157        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8158                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8159                modeFlags, false /*without considering the uid permissions*/);
8160
8161        // Second...  is the provider allowing granting of URI permissions?
8162        if (!specialCrossUserGrant) {
8163            if (!pi.grantUriPermissions) {
8164                throw new SecurityException("Provider " + pi.packageName
8165                        + "/" + pi.name
8166                        + " does not allow granting of Uri permissions (uri "
8167                        + grantUri + ")");
8168            }
8169            if (pi.uriPermissionPatterns != null) {
8170                final int N = pi.uriPermissionPatterns.length;
8171                boolean allowed = false;
8172                for (int i=0; i<N; i++) {
8173                    if (pi.uriPermissionPatterns[i] != null
8174                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8175                        allowed = true;
8176                        break;
8177                    }
8178                }
8179                if (!allowed) {
8180                    throw new SecurityException("Provider " + pi.packageName
8181                            + "/" + pi.name
8182                            + " does not allow granting of permission to path of Uri "
8183                            + grantUri);
8184                }
8185            }
8186        }
8187
8188        // Third...  does the caller itself have permission to access
8189        // this uri?
8190        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
8191            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8192                // Require they hold a strong enough Uri permission
8193                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8194                    throw new SecurityException("Uid " + callingUid
8195                            + " does not have permission to uri " + grantUri);
8196                }
8197            }
8198        }
8199        return targetUid;
8200    }
8201
8202    /**
8203     * @param uri This uri must NOT contain an embedded userId.
8204     * @param userId The userId in which the uri is to be resolved.
8205     */
8206    @Override
8207    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8208            final int modeFlags, int userId) {
8209        enforceNotIsolatedCaller("checkGrantUriPermission");
8210        synchronized(this) {
8211            return checkGrantUriPermissionLocked(callingUid, targetPkg,
8212                    new GrantUri(userId, uri, false), modeFlags, -1);
8213        }
8214    }
8215
8216    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8217            final int modeFlags, UriPermissionOwner owner) {
8218        if (!Intent.isAccessUriMode(modeFlags)) {
8219            return;
8220        }
8221
8222        // So here we are: the caller has the assumed permission
8223        // to the uri, and the target doesn't.  Let's now give this to
8224        // the target.
8225
8226        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8227                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8228
8229        final String authority = grantUri.uri.getAuthority();
8230        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8231                MATCH_DEBUG_TRIAGED_MISSING);
8232        if (pi == null) {
8233            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8234            return;
8235        }
8236
8237        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8238            grantUri.prefix = true;
8239        }
8240        final UriPermission perm = findOrCreateUriPermissionLocked(
8241                pi.packageName, targetPkg, targetUid, grantUri);
8242        perm.grantModes(modeFlags, owner);
8243    }
8244
8245    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8246            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8247        if (targetPkg == null) {
8248            throw new NullPointerException("targetPkg");
8249        }
8250        int targetUid;
8251        final IPackageManager pm = AppGlobals.getPackageManager();
8252        try {
8253            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8254        } catch (RemoteException ex) {
8255            return;
8256        }
8257
8258        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8259                targetUid);
8260        if (targetUid < 0) {
8261            return;
8262        }
8263
8264        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8265                owner);
8266    }
8267
8268    static class NeededUriGrants extends ArrayList<GrantUri> {
8269        final String targetPkg;
8270        final int targetUid;
8271        final int flags;
8272
8273        NeededUriGrants(String targetPkg, int targetUid, int flags) {
8274            this.targetPkg = targetPkg;
8275            this.targetUid = targetUid;
8276            this.flags = flags;
8277        }
8278    }
8279
8280    /**
8281     * Like checkGrantUriPermissionLocked, but takes an Intent.
8282     */
8283    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8284            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8285        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8286                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8287                + " clip=" + (intent != null ? intent.getClipData() : null)
8288                + " from " + intent + "; flags=0x"
8289                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8290
8291        if (targetPkg == null) {
8292            throw new NullPointerException("targetPkg");
8293        }
8294
8295        if (intent == null) {
8296            return null;
8297        }
8298        Uri data = intent.getData();
8299        ClipData clip = intent.getClipData();
8300        if (data == null && clip == null) {
8301            return null;
8302        }
8303        // Default userId for uris in the intent (if they don't specify it themselves)
8304        int contentUserHint = intent.getContentUserHint();
8305        if (contentUserHint == UserHandle.USER_CURRENT) {
8306            contentUserHint = UserHandle.getUserId(callingUid);
8307        }
8308        final IPackageManager pm = AppGlobals.getPackageManager();
8309        int targetUid;
8310        if (needed != null) {
8311            targetUid = needed.targetUid;
8312        } else {
8313            try {
8314                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8315                        targetUserId);
8316            } catch (RemoteException ex) {
8317                return null;
8318            }
8319            if (targetUid < 0) {
8320                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8321                        "Can't grant URI permission no uid for: " + targetPkg
8322                        + " on user " + targetUserId);
8323                return null;
8324            }
8325        }
8326        if (data != null) {
8327            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8328            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8329                    targetUid);
8330            if (targetUid > 0) {
8331                if (needed == null) {
8332                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8333                }
8334                needed.add(grantUri);
8335            }
8336        }
8337        if (clip != null) {
8338            for (int i=0; i<clip.getItemCount(); i++) {
8339                Uri uri = clip.getItemAt(i).getUri();
8340                if (uri != null) {
8341                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8342                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8343                            targetUid);
8344                    if (targetUid > 0) {
8345                        if (needed == null) {
8346                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8347                        }
8348                        needed.add(grantUri);
8349                    }
8350                } else {
8351                    Intent clipIntent = clip.getItemAt(i).getIntent();
8352                    if (clipIntent != null) {
8353                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8354                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8355                        if (newNeeded != null) {
8356                            needed = newNeeded;
8357                        }
8358                    }
8359                }
8360            }
8361        }
8362
8363        return needed;
8364    }
8365
8366    /**
8367     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8368     */
8369    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8370            UriPermissionOwner owner) {
8371        if (needed != null) {
8372            for (int i=0; i<needed.size(); i++) {
8373                GrantUri grantUri = needed.get(i);
8374                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8375                        grantUri, needed.flags, owner);
8376            }
8377        }
8378    }
8379
8380    void grantUriPermissionFromIntentLocked(int callingUid,
8381            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8382        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8383                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8384        if (needed == null) {
8385            return;
8386        }
8387
8388        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8389    }
8390
8391    /**
8392     * @param uri This uri must NOT contain an embedded userId.
8393     * @param userId The userId in which the uri is to be resolved.
8394     */
8395    @Override
8396    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8397            final int modeFlags, int userId) {
8398        enforceNotIsolatedCaller("grantUriPermission");
8399        GrantUri grantUri = new GrantUri(userId, uri, false);
8400        synchronized(this) {
8401            final ProcessRecord r = getRecordForAppLocked(caller);
8402            if (r == null) {
8403                throw new SecurityException("Unable to find app for caller "
8404                        + caller
8405                        + " when granting permission to uri " + grantUri);
8406            }
8407            if (targetPkg == null) {
8408                throw new IllegalArgumentException("null target");
8409            }
8410            if (grantUri == null) {
8411                throw new IllegalArgumentException("null uri");
8412            }
8413
8414            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8415                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8416                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8417                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8418
8419            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8420                    UserHandle.getUserId(r.uid));
8421        }
8422    }
8423
8424    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8425        if (perm.modeFlags == 0) {
8426            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8427                    perm.targetUid);
8428            if (perms != null) {
8429                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8430                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8431
8432                perms.remove(perm.uri);
8433                if (perms.isEmpty()) {
8434                    mGrantedUriPermissions.remove(perm.targetUid);
8435                }
8436            }
8437        }
8438    }
8439
8440    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8441        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8442                "Revoking all granted permissions to " + grantUri);
8443
8444        final IPackageManager pm = AppGlobals.getPackageManager();
8445        final String authority = grantUri.uri.getAuthority();
8446        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8447                MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8448        if (pi == null) {
8449            Slog.w(TAG, "No content provider found for permission revoke: "
8450                    + grantUri.toSafeString());
8451            return;
8452        }
8453
8454        // Does the caller have this permission on the URI?
8455        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8456            // If they don't have direct access to the URI, then revoke any
8457            // ownerless URI permissions that have been granted to them.
8458            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8459            if (perms != null) {
8460                boolean persistChanged = false;
8461                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8462                    final UriPermission perm = it.next();
8463                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8464                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8465                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8466                                "Revoking non-owned " + perm.targetUid
8467                                + " permission to " + perm.uri);
8468                        persistChanged |= perm.revokeModes(
8469                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8470                        if (perm.modeFlags == 0) {
8471                            it.remove();
8472                        }
8473                    }
8474                }
8475                if (perms.isEmpty()) {
8476                    mGrantedUriPermissions.remove(callingUid);
8477                }
8478                if (persistChanged) {
8479                    schedulePersistUriGrants();
8480                }
8481            }
8482            return;
8483        }
8484
8485        boolean persistChanged = false;
8486
8487        // Go through all of the permissions and remove any that match.
8488        int N = mGrantedUriPermissions.size();
8489        for (int i = 0; i < N; i++) {
8490            final int targetUid = mGrantedUriPermissions.keyAt(i);
8491            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8492
8493            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8494                final UriPermission perm = it.next();
8495                if (perm.uri.sourceUserId == grantUri.sourceUserId
8496                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8497                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8498                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8499                    persistChanged |= perm.revokeModes(
8500                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8501                    if (perm.modeFlags == 0) {
8502                        it.remove();
8503                    }
8504                }
8505            }
8506
8507            if (perms.isEmpty()) {
8508                mGrantedUriPermissions.remove(targetUid);
8509                N--;
8510                i--;
8511            }
8512        }
8513
8514        if (persistChanged) {
8515            schedulePersistUriGrants();
8516        }
8517    }
8518
8519    /**
8520     * @param uri This uri must NOT contain an embedded userId.
8521     * @param userId The userId in which the uri is to be resolved.
8522     */
8523    @Override
8524    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8525            int userId) {
8526        enforceNotIsolatedCaller("revokeUriPermission");
8527        synchronized(this) {
8528            final ProcessRecord r = getRecordForAppLocked(caller);
8529            if (r == null) {
8530                throw new SecurityException("Unable to find app for caller "
8531                        + caller
8532                        + " when revoking permission to uri " + uri);
8533            }
8534            if (uri == null) {
8535                Slog.w(TAG, "revokeUriPermission: null uri");
8536                return;
8537            }
8538
8539            if (!Intent.isAccessUriMode(modeFlags)) {
8540                return;
8541            }
8542
8543            final String authority = uri.getAuthority();
8544            final ProviderInfo pi = getProviderInfoLocked(authority, userId,
8545                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8546            if (pi == null) {
8547                Slog.w(TAG, "No content provider found for permission revoke: "
8548                        + uri.toSafeString());
8549                return;
8550            }
8551
8552            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8553        }
8554    }
8555
8556    /**
8557     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8558     * given package.
8559     *
8560     * @param packageName Package name to match, or {@code null} to apply to all
8561     *            packages.
8562     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8563     *            to all users.
8564     * @param persistable If persistable grants should be removed.
8565     */
8566    private void removeUriPermissionsForPackageLocked(
8567            String packageName, int userHandle, boolean persistable) {
8568        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8569            throw new IllegalArgumentException("Must narrow by either package or user");
8570        }
8571
8572        boolean persistChanged = false;
8573
8574        int N = mGrantedUriPermissions.size();
8575        for (int i = 0; i < N; i++) {
8576            final int targetUid = mGrantedUriPermissions.keyAt(i);
8577            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8578
8579            // Only inspect grants matching user
8580            if (userHandle == UserHandle.USER_ALL
8581                    || userHandle == UserHandle.getUserId(targetUid)) {
8582                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8583                    final UriPermission perm = it.next();
8584
8585                    // Only inspect grants matching package
8586                    if (packageName == null || perm.sourcePkg.equals(packageName)
8587                            || perm.targetPkg.equals(packageName)) {
8588                        persistChanged |= perm.revokeModes(persistable
8589                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8590
8591                        // Only remove when no modes remain; any persisted grants
8592                        // will keep this alive.
8593                        if (perm.modeFlags == 0) {
8594                            it.remove();
8595                        }
8596                    }
8597                }
8598
8599                if (perms.isEmpty()) {
8600                    mGrantedUriPermissions.remove(targetUid);
8601                    N--;
8602                    i--;
8603                }
8604            }
8605        }
8606
8607        if (persistChanged) {
8608            schedulePersistUriGrants();
8609        }
8610    }
8611
8612    @Override
8613    public IBinder newUriPermissionOwner(String name) {
8614        enforceNotIsolatedCaller("newUriPermissionOwner");
8615        synchronized(this) {
8616            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8617            return owner.getExternalTokenLocked();
8618        }
8619    }
8620
8621    @Override
8622    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8623        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8624        synchronized(this) {
8625            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8626            if (r == null) {
8627                throw new IllegalArgumentException("Activity does not exist; token="
8628                        + activityToken);
8629            }
8630            return r.getUriPermissionsLocked().getExternalTokenLocked();
8631        }
8632    }
8633    /**
8634     * @param uri This uri must NOT contain an embedded userId.
8635     * @param sourceUserId The userId in which the uri is to be resolved.
8636     * @param targetUserId The userId of the app that receives the grant.
8637     */
8638    @Override
8639    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8640            final int modeFlags, int sourceUserId, int targetUserId) {
8641        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8642                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8643                "grantUriPermissionFromOwner", null);
8644        synchronized(this) {
8645            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8646            if (owner == null) {
8647                throw new IllegalArgumentException("Unknown owner: " + token);
8648            }
8649            if (fromUid != Binder.getCallingUid()) {
8650                if (Binder.getCallingUid() != Process.myUid()) {
8651                    // Only system code can grant URI permissions on behalf
8652                    // of other users.
8653                    throw new SecurityException("nice try");
8654                }
8655            }
8656            if (targetPkg == null) {
8657                throw new IllegalArgumentException("null target");
8658            }
8659            if (uri == null) {
8660                throw new IllegalArgumentException("null uri");
8661            }
8662
8663            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8664                    modeFlags, owner, targetUserId);
8665        }
8666    }
8667
8668    /**
8669     * @param uri This uri must NOT contain an embedded userId.
8670     * @param userId The userId in which the uri is to be resolved.
8671     */
8672    @Override
8673    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8674        synchronized(this) {
8675            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8676            if (owner == null) {
8677                throw new IllegalArgumentException("Unknown owner: " + token);
8678            }
8679
8680            if (uri == null) {
8681                owner.removeUriPermissionsLocked(mode);
8682            } else {
8683                final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
8684                owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
8685            }
8686        }
8687    }
8688
8689    private void schedulePersistUriGrants() {
8690        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8691            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8692                    10 * DateUtils.SECOND_IN_MILLIS);
8693        }
8694    }
8695
8696    private void writeGrantedUriPermissions() {
8697        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8698
8699        // Snapshot permissions so we can persist without lock
8700        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8701        synchronized (this) {
8702            final int size = mGrantedUriPermissions.size();
8703            for (int i = 0; i < size; i++) {
8704                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8705                for (UriPermission perm : perms.values()) {
8706                    if (perm.persistedModeFlags != 0) {
8707                        persist.add(perm.snapshot());
8708                    }
8709                }
8710            }
8711        }
8712
8713        FileOutputStream fos = null;
8714        try {
8715            fos = mGrantFile.startWrite();
8716
8717            XmlSerializer out = new FastXmlSerializer();
8718            out.setOutput(fos, StandardCharsets.UTF_8.name());
8719            out.startDocument(null, true);
8720            out.startTag(null, TAG_URI_GRANTS);
8721            for (UriPermission.Snapshot perm : persist) {
8722                out.startTag(null, TAG_URI_GRANT);
8723                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8724                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8725                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8726                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8727                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8728                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8729                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8730                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8731                out.endTag(null, TAG_URI_GRANT);
8732            }
8733            out.endTag(null, TAG_URI_GRANTS);
8734            out.endDocument();
8735
8736            mGrantFile.finishWrite(fos);
8737        } catch (IOException e) {
8738            if (fos != null) {
8739                mGrantFile.failWrite(fos);
8740            }
8741        }
8742    }
8743
8744    private void readGrantedUriPermissionsLocked() {
8745        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8746
8747        final long now = System.currentTimeMillis();
8748
8749        FileInputStream fis = null;
8750        try {
8751            fis = mGrantFile.openRead();
8752            final XmlPullParser in = Xml.newPullParser();
8753            in.setInput(fis, StandardCharsets.UTF_8.name());
8754
8755            int type;
8756            while ((type = in.next()) != END_DOCUMENT) {
8757                final String tag = in.getName();
8758                if (type == START_TAG) {
8759                    if (TAG_URI_GRANT.equals(tag)) {
8760                        final int sourceUserId;
8761                        final int targetUserId;
8762                        final int userHandle = readIntAttribute(in,
8763                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8764                        if (userHandle != UserHandle.USER_NULL) {
8765                            // For backwards compatibility.
8766                            sourceUserId = userHandle;
8767                            targetUserId = userHandle;
8768                        } else {
8769                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8770                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8771                        }
8772                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8773                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8774                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8775                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8776                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8777                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8778
8779                        // Sanity check that provider still belongs to source package
8780                        // Both direct boot aware and unaware packages are fine as we
8781                        // will do filtering at query time to avoid multiple parsing.
8782                        final ProviderInfo pi = getProviderInfoLocked(
8783                                uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
8784                                        | MATCH_DIRECT_BOOT_UNAWARE);
8785                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8786                            int targetUid = -1;
8787                            try {
8788                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8789                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8790                            } catch (RemoteException e) {
8791                            }
8792                            if (targetUid != -1) {
8793                                final UriPermission perm = findOrCreateUriPermissionLocked(
8794                                        sourcePkg, targetPkg, targetUid,
8795                                        new GrantUri(sourceUserId, uri, prefix));
8796                                perm.initPersistedModes(modeFlags, createdTime);
8797                            }
8798                        } else {
8799                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8800                                    + " but instead found " + pi);
8801                        }
8802                    }
8803                }
8804            }
8805        } catch (FileNotFoundException e) {
8806            // Missing grants is okay
8807        } catch (IOException e) {
8808            Slog.wtf(TAG, "Failed reading Uri grants", e);
8809        } catch (XmlPullParserException e) {
8810            Slog.wtf(TAG, "Failed reading Uri grants", e);
8811        } finally {
8812            IoUtils.closeQuietly(fis);
8813        }
8814    }
8815
8816    /**
8817     * @param uri This uri must NOT contain an embedded userId.
8818     * @param userId The userId in which the uri is to be resolved.
8819     */
8820    @Override
8821    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8822        enforceNotIsolatedCaller("takePersistableUriPermission");
8823
8824        Preconditions.checkFlagsArgument(modeFlags,
8825                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8826
8827        synchronized (this) {
8828            final int callingUid = Binder.getCallingUid();
8829            boolean persistChanged = false;
8830            GrantUri grantUri = new GrantUri(userId, uri, false);
8831
8832            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8833                    new GrantUri(userId, uri, false));
8834            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8835                    new GrantUri(userId, uri, true));
8836
8837            final boolean exactValid = (exactPerm != null)
8838                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8839            final boolean prefixValid = (prefixPerm != null)
8840                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8841
8842            if (!(exactValid || prefixValid)) {
8843                throw new SecurityException("No persistable permission grants found for UID "
8844                        + callingUid + " and Uri " + grantUri.toSafeString());
8845            }
8846
8847            if (exactValid) {
8848                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8849            }
8850            if (prefixValid) {
8851                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8852            }
8853
8854            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8855
8856            if (persistChanged) {
8857                schedulePersistUriGrants();
8858            }
8859        }
8860    }
8861
8862    /**
8863     * @param uri This uri must NOT contain an embedded userId.
8864     * @param userId The userId in which the uri is to be resolved.
8865     */
8866    @Override
8867    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8868        enforceNotIsolatedCaller("releasePersistableUriPermission");
8869
8870        Preconditions.checkFlagsArgument(modeFlags,
8871                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8872
8873        synchronized (this) {
8874            final int callingUid = Binder.getCallingUid();
8875            boolean persistChanged = false;
8876
8877            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8878                    new GrantUri(userId, uri, false));
8879            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8880                    new GrantUri(userId, uri, true));
8881            if (exactPerm == null && prefixPerm == null) {
8882                throw new SecurityException("No permission grants found for UID " + callingUid
8883                        + " and Uri " + uri.toSafeString());
8884            }
8885
8886            if (exactPerm != null) {
8887                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8888                removeUriPermissionIfNeededLocked(exactPerm);
8889            }
8890            if (prefixPerm != null) {
8891                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8892                removeUriPermissionIfNeededLocked(prefixPerm);
8893            }
8894
8895            if (persistChanged) {
8896                schedulePersistUriGrants();
8897            }
8898        }
8899    }
8900
8901    /**
8902     * Prune any older {@link UriPermission} for the given UID until outstanding
8903     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8904     *
8905     * @return if any mutations occured that require persisting.
8906     */
8907    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8908        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8909        if (perms == null) return false;
8910        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8911
8912        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8913        for (UriPermission perm : perms.values()) {
8914            if (perm.persistedModeFlags != 0) {
8915                persisted.add(perm);
8916            }
8917        }
8918
8919        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8920        if (trimCount <= 0) return false;
8921
8922        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8923        for (int i = 0; i < trimCount; i++) {
8924            final UriPermission perm = persisted.get(i);
8925
8926            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8927                    "Trimming grant created at " + perm.persistedCreateTime);
8928
8929            perm.releasePersistableModes(~0);
8930            removeUriPermissionIfNeededLocked(perm);
8931        }
8932
8933        return true;
8934    }
8935
8936    @Override
8937    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8938            String packageName, boolean incoming) {
8939        enforceNotIsolatedCaller("getPersistedUriPermissions");
8940        Preconditions.checkNotNull(packageName, "packageName");
8941
8942        final int callingUid = Binder.getCallingUid();
8943        final int callingUserId = UserHandle.getUserId(callingUid);
8944        final IPackageManager pm = AppGlobals.getPackageManager();
8945        try {
8946            final int packageUid = pm.getPackageUid(packageName,
8947                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
8948            if (packageUid != callingUid) {
8949                throw new SecurityException(
8950                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8951            }
8952        } catch (RemoteException e) {
8953            throw new SecurityException("Failed to verify package name ownership");
8954        }
8955
8956        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8957        synchronized (this) {
8958            if (incoming) {
8959                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8960                        callingUid);
8961                if (perms == null) {
8962                    Slog.w(TAG, "No permission grants found for " + packageName);
8963                } else {
8964                    for (UriPermission perm : perms.values()) {
8965                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8966                            result.add(perm.buildPersistedPublicApiObject());
8967                        }
8968                    }
8969                }
8970            } else {
8971                final int size = mGrantedUriPermissions.size();
8972                for (int i = 0; i < size; i++) {
8973                    final ArrayMap<GrantUri, UriPermission> perms =
8974                            mGrantedUriPermissions.valueAt(i);
8975                    for (UriPermission perm : perms.values()) {
8976                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8977                            result.add(perm.buildPersistedPublicApiObject());
8978                        }
8979                    }
8980                }
8981            }
8982        }
8983        return new ParceledListSlice<android.content.UriPermission>(result);
8984    }
8985
8986    @Override
8987    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8988            String packageName, int userId) {
8989        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8990                "getGrantedUriPermissions");
8991
8992        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8993        synchronized (this) {
8994            final int size = mGrantedUriPermissions.size();
8995            for (int i = 0; i < size; i++) {
8996                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8997                for (UriPermission perm : perms.values()) {
8998                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8999                            && perm.persistedModeFlags != 0) {
9000                        result.add(perm.buildPersistedPublicApiObject());
9001                    }
9002                }
9003            }
9004        }
9005        return new ParceledListSlice<android.content.UriPermission>(result);
9006    }
9007
9008    @Override
9009    public void clearGrantedUriPermissions(String packageName, int userId) {
9010        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
9011                "clearGrantedUriPermissions");
9012        removeUriPermissionsForPackageLocked(packageName, userId, true);
9013    }
9014
9015    @Override
9016    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
9017        synchronized (this) {
9018            ProcessRecord app =
9019                who != null ? getRecordForAppLocked(who) : null;
9020            if (app == null) return;
9021
9022            Message msg = Message.obtain();
9023            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
9024            msg.obj = app;
9025            msg.arg1 = waiting ? 1 : 0;
9026            mUiHandler.sendMessage(msg);
9027        }
9028    }
9029
9030    @Override
9031    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
9032        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
9033        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
9034        outInfo.availMem = Process.getFreeMemory();
9035        outInfo.totalMem = Process.getTotalMemory();
9036        outInfo.threshold = homeAppMem;
9037        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
9038        outInfo.hiddenAppThreshold = cachedAppMem;
9039        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
9040                ProcessList.SERVICE_ADJ);
9041        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
9042                ProcessList.VISIBLE_APP_ADJ);
9043        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
9044                ProcessList.FOREGROUND_APP_ADJ);
9045    }
9046
9047    // =========================================================
9048    // TASK MANAGEMENT
9049    // =========================================================
9050
9051    @Override
9052    public List<IAppTask> getAppTasks(String callingPackage) {
9053        int callingUid = Binder.getCallingUid();
9054        long ident = Binder.clearCallingIdentity();
9055
9056        synchronized(this) {
9057            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
9058            try {
9059                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
9060
9061                final int N = mRecentTasks.size();
9062                for (int i = 0; i < N; i++) {
9063                    TaskRecord tr = mRecentTasks.get(i);
9064                    // Skip tasks that do not match the caller.  We don't need to verify
9065                    // callingPackage, because we are also limiting to callingUid and know
9066                    // that will limit to the correct security sandbox.
9067                    if (tr.effectiveUid != callingUid) {
9068                        continue;
9069                    }
9070                    Intent intent = tr.getBaseIntent();
9071                    if (intent == null ||
9072                            !callingPackage.equals(intent.getComponent().getPackageName())) {
9073                        continue;
9074                    }
9075                    ActivityManager.RecentTaskInfo taskInfo =
9076                            createRecentTaskInfoFromTaskRecord(tr);
9077                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
9078                    list.add(taskImpl);
9079                }
9080            } finally {
9081                Binder.restoreCallingIdentity(ident);
9082            }
9083            return list;
9084        }
9085    }
9086
9087    @Override
9088    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9089        final int callingUid = Binder.getCallingUid();
9090        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9091
9092        synchronized(this) {
9093            if (DEBUG_ALL) Slog.v(
9094                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9095
9096            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9097                    callingUid);
9098
9099            // TODO: Improve with MRU list from all ActivityStacks.
9100            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9101        }
9102
9103        return list;
9104    }
9105
9106    /**
9107     * Creates a new RecentTaskInfo from a TaskRecord.
9108     */
9109    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9110        // Update the task description to reflect any changes in the task stack
9111        tr.updateTaskDescription();
9112
9113        // Compose the recent task info
9114        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9115        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9116        rti.persistentId = tr.taskId;
9117        rti.baseIntent = new Intent(tr.getBaseIntent());
9118        rti.origActivity = tr.origActivity;
9119        rti.realActivity = tr.realActivity;
9120        rti.description = tr.lastDescription;
9121        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
9122        rti.userId = tr.userId;
9123        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9124        rti.firstActiveTime = tr.firstActiveTime;
9125        rti.lastActiveTime = tr.lastActiveTime;
9126        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9127        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9128        rti.numActivities = 0;
9129        if (tr.mBounds != null) {
9130            rti.bounds = new Rect(tr.mBounds);
9131        }
9132        rti.isDockable = tr.canGoInDockedStack();
9133        rti.resizeMode = tr.mResizeMode;
9134
9135        ActivityRecord base = null;
9136        ActivityRecord top = null;
9137        ActivityRecord tmp;
9138
9139        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9140            tmp = tr.mActivities.get(i);
9141            if (tmp.finishing) {
9142                continue;
9143            }
9144            base = tmp;
9145            if (top == null || (top.state == ActivityState.INITIALIZING)) {
9146                top = base;
9147            }
9148            rti.numActivities++;
9149        }
9150
9151        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9152        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9153
9154        return rti;
9155    }
9156
9157    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9158        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9159                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9160        if (!allowed) {
9161            if (checkPermission(android.Manifest.permission.GET_TASKS,
9162                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9163                // Temporary compatibility: some existing apps on the system image may
9164                // still be requesting the old permission and not switched to the new
9165                // one; if so, we'll still allow them full access.  This means we need
9166                // to see if they are holding the old permission and are a system app.
9167                try {
9168                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9169                        allowed = true;
9170                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9171                                + " is using old GET_TASKS but privileged; allowing");
9172                    }
9173                } catch (RemoteException e) {
9174                }
9175            }
9176        }
9177        if (!allowed) {
9178            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9179                    + " does not hold REAL_GET_TASKS; limiting output");
9180        }
9181        return allowed;
9182    }
9183
9184    @Override
9185    public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9186            int userId) {
9187        final int callingUid = Binder.getCallingUid();
9188        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9189                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9190
9191        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9192        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9193        synchronized (this) {
9194            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9195                    callingUid);
9196            final boolean detailed = checkCallingPermission(
9197                    android.Manifest.permission.GET_DETAILED_TASKS)
9198                    == PackageManager.PERMISSION_GRANTED;
9199
9200            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9201                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9202                return ParceledListSlice.emptyList();
9203            }
9204            mRecentTasks.loadUserRecentsLocked(userId);
9205
9206            final int recentsCount = mRecentTasks.size();
9207            ArrayList<ActivityManager.RecentTaskInfo> res =
9208                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9209
9210            final Set<Integer> includedUsers;
9211            if (includeProfiles) {
9212                includedUsers = mUserController.getProfileIds(userId);
9213            } else {
9214                includedUsers = new HashSet<>();
9215            }
9216            includedUsers.add(Integer.valueOf(userId));
9217
9218            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9219                TaskRecord tr = mRecentTasks.get(i);
9220                // Only add calling user or related users recent tasks
9221                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9222                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9223                    continue;
9224                }
9225
9226                if (tr.realActivitySuspended) {
9227                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9228                    continue;
9229                }
9230
9231                // Return the entry if desired by the caller.  We always return
9232                // the first entry, because callers always expect this to be the
9233                // foreground app.  We may filter others if the caller has
9234                // not supplied RECENT_WITH_EXCLUDED and there is some reason
9235                // we should exclude the entry.
9236
9237                if (i == 0
9238                        || withExcluded
9239                        || (tr.intent == null)
9240                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9241                                == 0)) {
9242                    if (!allowed) {
9243                        // If the caller doesn't have the GET_TASKS permission, then only
9244                        // allow them to see a small subset of tasks -- their own and home.
9245                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9246                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9247                            continue;
9248                        }
9249                    }
9250                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
9251                        if (tr.stack != null && tr.stack.isHomeStack()) {
9252                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9253                                    "Skipping, home stack task: " + tr);
9254                            continue;
9255                        }
9256                    }
9257                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9258                        final ActivityStack stack = tr.stack;
9259                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9260                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9261                                    "Skipping, top task in docked stack: " + tr);
9262                            continue;
9263                        }
9264                    }
9265                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9266                        if (tr.stack != null && tr.stack.isPinnedStack()) {
9267                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9268                                    "Skipping, pinned stack task: " + tr);
9269                            continue;
9270                        }
9271                    }
9272                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9273                        // Don't include auto remove tasks that are finished or finishing.
9274                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9275                                "Skipping, auto-remove without activity: " + tr);
9276                        continue;
9277                    }
9278                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9279                            && !tr.isAvailable) {
9280                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9281                                "Skipping, unavail real act: " + tr);
9282                        continue;
9283                    }
9284
9285                    if (!tr.mUserSetupComplete) {
9286                        // Don't include task launched while user is not done setting-up.
9287                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9288                                "Skipping, user setup not complete: " + tr);
9289                        continue;
9290                    }
9291
9292                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9293                    if (!detailed) {
9294                        rti.baseIntent.replaceExtras((Bundle)null);
9295                    }
9296
9297                    res.add(rti);
9298                    maxNum--;
9299                }
9300            }
9301            return new ParceledListSlice<>(res);
9302        }
9303    }
9304
9305    @Override
9306    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9307        synchronized (this) {
9308            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9309                    "getTaskThumbnail()");
9310            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9311                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9312            if (tr != null) {
9313                return tr.getTaskThumbnailLocked();
9314            }
9315        }
9316        return null;
9317    }
9318
9319    @Override
9320    public int addAppTask(IBinder activityToken, Intent intent,
9321            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9322        final int callingUid = Binder.getCallingUid();
9323        final long callingIdent = Binder.clearCallingIdentity();
9324
9325        try {
9326            synchronized (this) {
9327                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9328                if (r == null) {
9329                    throw new IllegalArgumentException("Activity does not exist; token="
9330                            + activityToken);
9331                }
9332                ComponentName comp = intent.getComponent();
9333                if (comp == null) {
9334                    throw new IllegalArgumentException("Intent " + intent
9335                            + " must specify explicit component");
9336                }
9337                if (thumbnail.getWidth() != mThumbnailWidth
9338                        || thumbnail.getHeight() != mThumbnailHeight) {
9339                    throw new IllegalArgumentException("Bad thumbnail size: got "
9340                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9341                            + mThumbnailWidth + "x" + mThumbnailHeight);
9342                }
9343                if (intent.getSelector() != null) {
9344                    intent.setSelector(null);
9345                }
9346                if (intent.getSourceBounds() != null) {
9347                    intent.setSourceBounds(null);
9348                }
9349                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9350                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9351                        // The caller has added this as an auto-remove task...  that makes no
9352                        // sense, so turn off auto-remove.
9353                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9354                    }
9355                }
9356                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9357                    mLastAddedTaskActivity = null;
9358                }
9359                ActivityInfo ainfo = mLastAddedTaskActivity;
9360                if (ainfo == null) {
9361                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9362                            comp, 0, UserHandle.getUserId(callingUid));
9363                    if (ainfo.applicationInfo.uid != callingUid) {
9364                        throw new SecurityException(
9365                                "Can't add task for another application: target uid="
9366                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9367                    }
9368                }
9369
9370                // Use the full screen as the context for the task thumbnail
9371                final Point displaySize = new Point();
9372                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9373                r.task.stack.getDisplaySize(displaySize);
9374                thumbnailInfo.taskWidth = displaySize.x;
9375                thumbnailInfo.taskHeight = displaySize.y;
9376                thumbnailInfo.screenOrientation = mConfiguration.orientation;
9377
9378                TaskRecord task = new TaskRecord(this,
9379                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9380                        ainfo, intent, description, thumbnailInfo);
9381
9382                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9383                if (trimIdx >= 0) {
9384                    // If this would have caused a trim, then we'll abort because that
9385                    // means it would be added at the end of the list but then just removed.
9386                    return INVALID_TASK_ID;
9387                }
9388
9389                final int N = mRecentTasks.size();
9390                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9391                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9392                    tr.removedFromRecents();
9393                }
9394
9395                task.inRecents = true;
9396                mRecentTasks.add(task);
9397                r.task.stack.addTask(task, false, "addAppTask");
9398
9399                task.setLastThumbnailLocked(thumbnail);
9400                task.freeLastThumbnail();
9401
9402                return task.taskId;
9403            }
9404        } finally {
9405            Binder.restoreCallingIdentity(callingIdent);
9406        }
9407    }
9408
9409    @Override
9410    public Point getAppTaskThumbnailSize() {
9411        synchronized (this) {
9412            return new Point(mThumbnailWidth,  mThumbnailHeight);
9413        }
9414    }
9415
9416    @Override
9417    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9418        synchronized (this) {
9419            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9420            if (r != null) {
9421                r.setTaskDescription(td);
9422                r.task.updateTaskDescription();
9423            }
9424        }
9425    }
9426
9427    @Override
9428    public void setTaskResizeable(int taskId, int resizeableMode) {
9429        synchronized (this) {
9430            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9431                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9432            if (task == null) {
9433                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9434                return;
9435            }
9436            if (task.mResizeMode != resizeableMode) {
9437                task.mResizeMode = resizeableMode;
9438                mWindowManager.setTaskResizeable(taskId, resizeableMode);
9439                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9440                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9441            }
9442        }
9443    }
9444
9445    @Override
9446    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9447        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9448        long ident = Binder.clearCallingIdentity();
9449        try {
9450            synchronized (this) {
9451                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9452                if (task == null) {
9453                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9454                    return;
9455                }
9456                int stackId = task.stack.mStackId;
9457                // We allow the task to scroll instead of resizing if this is a non-resizeable task
9458                // in crop windows resize mode or if the task size is affected by the docked stack
9459                // changing size. No need to update configuration.
9460                if (bounds != null && task.inCropWindowsResizeMode()
9461                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
9462                    mWindowManager.scrollTask(task.taskId, bounds);
9463                    return;
9464                }
9465
9466                // Place the task in the right stack if it isn't there already based on
9467                // the requested bounds.
9468                // The stack transition logic is:
9469                // - a null bounds on a freeform task moves that task to fullscreen
9470                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9471                //   that task to freeform
9472                // - otherwise the task is not moved
9473                if (!StackId.isTaskResizeAllowed(stackId)) {
9474                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9475                }
9476                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9477                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9478                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9479                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9480                }
9481                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9482                if (stackId != task.stack.mStackId) {
9483                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9484                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9485                    preserveWindow = false;
9486                }
9487
9488                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9489                        false /* deferResume */);
9490            }
9491        } finally {
9492            Binder.restoreCallingIdentity(ident);
9493        }
9494    }
9495
9496    @Override
9497    public Rect getTaskBounds(int taskId) {
9498        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9499        long ident = Binder.clearCallingIdentity();
9500        Rect rect = new Rect();
9501        try {
9502            synchronized (this) {
9503                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9504                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9505                if (task == null) {
9506                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9507                    return rect;
9508                }
9509                if (task.stack != null) {
9510                    // Return the bounds from window manager since it will be adjusted for various
9511                    // things like the presense of a docked stack for tasks that aren't resizeable.
9512                    mWindowManager.getTaskBounds(task.taskId, rect);
9513                } else {
9514                    // Task isn't in window manager yet since it isn't associated with a stack.
9515                    // Return the persist value from activity manager
9516                    if (task.mBounds != null) {
9517                        rect.set(task.mBounds);
9518                    } else if (task.mLastNonFullscreenBounds != null) {
9519                        rect.set(task.mLastNonFullscreenBounds);
9520                    }
9521                }
9522            }
9523        } finally {
9524            Binder.restoreCallingIdentity(ident);
9525        }
9526        return rect;
9527    }
9528
9529    @Override
9530    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9531        if (userId != UserHandle.getCallingUserId()) {
9532            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9533                    "getTaskDescriptionIcon");
9534        }
9535        final File passedIconFile = new File(filePath);
9536        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9537                passedIconFile.getName());
9538        if (!legitIconFile.getPath().equals(filePath)
9539                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9540            throw new IllegalArgumentException("Bad file path: " + filePath
9541                    + " passed for userId " + userId);
9542        }
9543        return mRecentTasks.getTaskDescriptionIcon(filePath);
9544    }
9545
9546    @Override
9547    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9548            throws RemoteException {
9549        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9550                opts.getCustomInPlaceResId() == 0) {
9551            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9552                    "with valid animation");
9553        }
9554        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9555        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9556                opts.getCustomInPlaceResId());
9557        mWindowManager.executeAppTransition();
9558    }
9559
9560    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9561            boolean removeFromRecents) {
9562        if (removeFromRecents) {
9563            mRecentTasks.remove(tr);
9564            tr.removedFromRecents();
9565        }
9566        ComponentName component = tr.getBaseIntent().getComponent();
9567        if (component == null) {
9568            Slog.w(TAG, "No component for base intent of task: " + tr);
9569            return;
9570        }
9571
9572        // Find any running services associated with this app and stop if needed.
9573        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9574
9575        if (!killProcess) {
9576            return;
9577        }
9578
9579        // Determine if the process(es) for this task should be killed.
9580        final String pkg = component.getPackageName();
9581        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9582        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9583        for (int i = 0; i < pmap.size(); i++) {
9584
9585            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9586            for (int j = 0; j < uids.size(); j++) {
9587                ProcessRecord proc = uids.valueAt(j);
9588                if (proc.userId != tr.userId) {
9589                    // Don't kill process for a different user.
9590                    continue;
9591                }
9592                if (proc == mHomeProcess) {
9593                    // Don't kill the home process along with tasks from the same package.
9594                    continue;
9595                }
9596                if (!proc.pkgList.containsKey(pkg)) {
9597                    // Don't kill process that is not associated with this task.
9598                    continue;
9599                }
9600
9601                for (int k = 0; k < proc.activities.size(); k++) {
9602                    TaskRecord otherTask = proc.activities.get(k).task;
9603                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9604                        // Don't kill process(es) that has an activity in a different task that is
9605                        // also in recents.
9606                        return;
9607                    }
9608                }
9609
9610                if (proc.foregroundServices) {
9611                    // Don't kill process(es) with foreground service.
9612                    return;
9613                }
9614
9615                // Add process to kill list.
9616                procsToKill.add(proc);
9617            }
9618        }
9619
9620        // Kill the running processes.
9621        for (int i = 0; i < procsToKill.size(); i++) {
9622            ProcessRecord pr = procsToKill.get(i);
9623            if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9624                    && pr.curReceivers.isEmpty()) {
9625                pr.kill("remove task", true);
9626            } else {
9627                // We delay killing processes that are not in the background or running a receiver.
9628                pr.waitingToKill = "remove task";
9629            }
9630        }
9631    }
9632
9633    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9634        // Remove all tasks with activities in the specified package from the list of recent tasks
9635        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9636            TaskRecord tr = mRecentTasks.get(i);
9637            if (tr.userId != userId) continue;
9638
9639            ComponentName cn = tr.intent.getComponent();
9640            if (cn != null && cn.getPackageName().equals(packageName)) {
9641                // If the package name matches, remove the task.
9642                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9643            }
9644        }
9645    }
9646
9647    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9648            int userId) {
9649
9650        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9651            TaskRecord tr = mRecentTasks.get(i);
9652            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9653                continue;
9654            }
9655
9656            ComponentName cn = tr.intent.getComponent();
9657            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9658                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9659            if (sameComponent) {
9660                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9661            }
9662        }
9663    }
9664
9665    /**
9666     * Removes the task with the specified task id.
9667     *
9668     * @param taskId Identifier of the task to be removed.
9669     * @param killProcess Kill any process associated with the task if possible.
9670     * @param removeFromRecents Whether to also remove the task from recents.
9671     * @return Returns true if the given task was found and removed.
9672     */
9673    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9674            boolean removeFromRecents) {
9675        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9676                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9677        if (tr != null) {
9678            tr.removeTaskActivitiesLocked();
9679            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9680            if (tr.isPersistable) {
9681                notifyTaskPersisterLocked(null, true);
9682            }
9683            return true;
9684        }
9685        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9686        return false;
9687    }
9688
9689    @Override
9690    public void removeStack(int stackId) {
9691        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9692        if (stackId == HOME_STACK_ID) {
9693            throw new IllegalArgumentException("Removing home stack is not allowed.");
9694        }
9695
9696        synchronized (this) {
9697            final long ident = Binder.clearCallingIdentity();
9698            try {
9699                final ActivityStack stack = mStackSupervisor.getStack(stackId);
9700                if (stack == null) {
9701                    return;
9702                }
9703                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9704                for (int i = tasks.size() - 1; i >= 0; i--) {
9705                    removeTaskByIdLocked(
9706                            tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9707                }
9708            } finally {
9709                Binder.restoreCallingIdentity(ident);
9710            }
9711        }
9712    }
9713
9714    @Override
9715    public boolean removeTask(int taskId) {
9716        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9717        synchronized (this) {
9718            final long ident = Binder.clearCallingIdentity();
9719            try {
9720                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9721            } finally {
9722                Binder.restoreCallingIdentity(ident);
9723            }
9724        }
9725    }
9726
9727    /**
9728     * TODO: Add mController hook
9729     */
9730    @Override
9731    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9732        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9733
9734        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9735        synchronized(this) {
9736            moveTaskToFrontLocked(taskId, flags, bOptions);
9737        }
9738    }
9739
9740    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9741        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9742
9743        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9744                Binder.getCallingUid(), -1, -1, "Task to front")) {
9745            ActivityOptions.abort(options);
9746            return;
9747        }
9748        final long origId = Binder.clearCallingIdentity();
9749        try {
9750            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9751            if (task == null) {
9752                Slog.d(TAG, "Could not find task for id: "+ taskId);
9753                return;
9754            }
9755            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9756                mStackSupervisor.showLockTaskToast();
9757                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9758                return;
9759            }
9760            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9761            if (prev != null && prev.isRecentsActivity()) {
9762                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9763            }
9764            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9765                    false /* forceNonResizable */);
9766        } finally {
9767            Binder.restoreCallingIdentity(origId);
9768        }
9769        ActivityOptions.abort(options);
9770    }
9771
9772    /**
9773     * Moves an activity, and all of the other activities within the same task, to the bottom
9774     * of the history stack.  The activity's order within the task is unchanged.
9775     *
9776     * @param token A reference to the activity we wish to move
9777     * @param nonRoot If false then this only works if the activity is the root
9778     *                of a task; if true it will work for any activity in a task.
9779     * @return Returns true if the move completed, false if not.
9780     */
9781    @Override
9782    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9783        enforceNotIsolatedCaller("moveActivityTaskToBack");
9784        synchronized(this) {
9785            final long origId = Binder.clearCallingIdentity();
9786            try {
9787                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9788                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9789                if (task != null) {
9790                    if (mStackSupervisor.isLockedTask(task)) {
9791                        mStackSupervisor.showLockTaskToast();
9792                        return false;
9793                    }
9794                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9795                }
9796            } finally {
9797                Binder.restoreCallingIdentity(origId);
9798            }
9799        }
9800        return false;
9801    }
9802
9803    @Override
9804    public void moveTaskBackwards(int task) {
9805        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9806                "moveTaskBackwards()");
9807
9808        synchronized(this) {
9809            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9810                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9811                return;
9812            }
9813            final long origId = Binder.clearCallingIdentity();
9814            moveTaskBackwardsLocked(task);
9815            Binder.restoreCallingIdentity(origId);
9816        }
9817    }
9818
9819    private final void moveTaskBackwardsLocked(int task) {
9820        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9821    }
9822
9823    @Override
9824    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9825            IActivityContainerCallback callback) throws RemoteException {
9826        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9827        synchronized (this) {
9828            if (parentActivityToken == null) {
9829                throw new IllegalArgumentException("parent token must not be null");
9830            }
9831            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9832            if (r == null) {
9833                return null;
9834            }
9835            if (callback == null) {
9836                throw new IllegalArgumentException("callback must not be null");
9837            }
9838            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9839        }
9840    }
9841
9842    @Override
9843    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9844        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9845        synchronized (this) {
9846            mStackSupervisor.deleteActivityContainer(container);
9847        }
9848    }
9849
9850    @Override
9851    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9852        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9853        synchronized (this) {
9854            final int stackId = mStackSupervisor.getNextStackId();
9855            final ActivityStack stack =
9856                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9857            if (stack == null) {
9858                return null;
9859            }
9860            return stack.mActivityContainer;
9861        }
9862    }
9863
9864    @Override
9865    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9866        synchronized (this) {
9867            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9868            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9869                return stack.mActivityContainer.getDisplayId();
9870            }
9871            return Display.DEFAULT_DISPLAY;
9872        }
9873    }
9874
9875    @Override
9876    public int getActivityStackId(IBinder token) throws RemoteException {
9877        synchronized (this) {
9878            ActivityStack stack = ActivityRecord.getStackLocked(token);
9879            if (stack == null) {
9880                return INVALID_STACK_ID;
9881            }
9882            return stack.mStackId;
9883        }
9884    }
9885
9886    @Override
9887    public void exitFreeformMode(IBinder token) throws RemoteException {
9888        synchronized (this) {
9889            long ident = Binder.clearCallingIdentity();
9890            try {
9891                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9892                if (r == null) {
9893                    throw new IllegalArgumentException(
9894                            "exitFreeformMode: No activity record matching token=" + token);
9895                }
9896                final ActivityStack stack = r.getStackLocked(token);
9897                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9898                    throw new IllegalStateException(
9899                            "exitFreeformMode: You can only go fullscreen from freeform.");
9900                }
9901                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9902                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9903                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9904            } finally {
9905                Binder.restoreCallingIdentity(ident);
9906            }
9907        }
9908    }
9909
9910    @Override
9911    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9912        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9913        if (stackId == HOME_STACK_ID) {
9914            throw new IllegalArgumentException(
9915                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9916        }
9917        synchronized (this) {
9918            long ident = Binder.clearCallingIdentity();
9919            try {
9920                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9921                        + " to stackId=" + stackId + " toTop=" + toTop);
9922                if (stackId == DOCKED_STACK_ID) {
9923                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9924                            null /* initialBounds */);
9925                }
9926                boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9927                        !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9928                if (result && stackId == DOCKED_STACK_ID) {
9929                    // If task moved to docked stack - show recents if needed.
9930                    mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9931                            "moveTaskToDockedStack");
9932                }
9933            } finally {
9934                Binder.restoreCallingIdentity(ident);
9935            }
9936        }
9937    }
9938
9939    @Override
9940    public void swapDockedAndFullscreenStack() throws RemoteException {
9941        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9942        synchronized (this) {
9943            long ident = Binder.clearCallingIdentity();
9944            try {
9945                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9946                        FULLSCREEN_WORKSPACE_STACK_ID);
9947                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9948                        : null;
9949                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9950                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9951                        : null;
9952                if (topTask == null || tasks == null || tasks.size() == 0) {
9953                    Slog.w(TAG,
9954                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
9955                    return;
9956                }
9957
9958                // TODO: App transition
9959                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9960
9961                // Defer the resume so resume/pausing while moving stacks is dangerous.
9962                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9963                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9964                        ANIMATE, true /* deferResume */);
9965                final int size = tasks.size();
9966                for (int i = 0; i < size; i++) {
9967                    final int id = tasks.get(i).taskId;
9968                    if (id == topTask.taskId) {
9969                        continue;
9970                    }
9971                    mStackSupervisor.moveTaskToStackLocked(id,
9972                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9973                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9974                }
9975
9976                // Because we deferred the resume, to avoid conflicts with stack switches while
9977                // resuming, we need to do it after all the tasks are moved.
9978                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9979                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9980
9981                mWindowManager.executeAppTransition();
9982            } finally {
9983                Binder.restoreCallingIdentity(ident);
9984            }
9985        }
9986    }
9987
9988    /**
9989     * Moves the input task to the docked stack.
9990     *
9991     * @param taskId Id of task to move.
9992     * @param createMode The mode the docked stack should be created in if it doesn't exist
9993     *                   already. See
9994     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9995     *                   and
9996     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9997     * @param toTop If the task and stack should be moved to the top.
9998     * @param animate Whether we should play an animation for the moving the task
9999     * @param initialBounds If the docked stack gets created, it will use these bounds for the
10000     *                      docked stack. Pass {@code null} to use default bounds.
10001     */
10002    @Override
10003    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
10004            Rect initialBounds, boolean moveHomeStackFront) {
10005        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
10006        synchronized (this) {
10007            long ident = Binder.clearCallingIdentity();
10008            try {
10009                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
10010                        + " to createMode=" + createMode + " toTop=" + toTop);
10011                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
10012                final boolean moved = mStackSupervisor.moveTaskToStackLocked(
10013                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
10014                        animate, DEFER_RESUME);
10015                if (moved) {
10016                    if (moveHomeStackFront) {
10017                        mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
10018                    }
10019                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10020                }
10021                return moved;
10022            } finally {
10023                Binder.restoreCallingIdentity(ident);
10024            }
10025        }
10026    }
10027
10028    /**
10029     * Moves the top activity in the input stackId to the pinned stack.
10030     *
10031     * @param stackId Id of stack to move the top activity to pinned stack.
10032     * @param bounds Bounds to use for pinned stack.
10033     *
10034     * @return True if the top activity of the input stack was successfully moved to the pinned
10035     *          stack.
10036     */
10037    @Override
10038    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
10039        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
10040        synchronized (this) {
10041            if (!mSupportsPictureInPicture) {
10042                throw new IllegalStateException("moveTopActivityToPinnedStack:"
10043                        + "Device doesn't support picture-in-pciture mode");
10044            }
10045
10046            long ident = Binder.clearCallingIdentity();
10047            try {
10048                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
10049            } finally {
10050                Binder.restoreCallingIdentity(ident);
10051            }
10052        }
10053    }
10054
10055    @Override
10056    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
10057            boolean preserveWindows, boolean animate, int animationDuration) {
10058        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
10059        long ident = Binder.clearCallingIdentity();
10060        try {
10061            synchronized (this) {
10062                if (animate) {
10063                    if (stackId == PINNED_STACK_ID) {
10064                        mWindowManager.animateResizePinnedStack(bounds, animationDuration);
10065                    } else {
10066                        throw new IllegalArgumentException("Stack: " + stackId
10067                                + " doesn't support animated resize.");
10068                    }
10069                } else {
10070                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
10071                            null /* tempTaskInsetBounds */, preserveWindows,
10072                            allowResizeInDockedMode, !DEFER_RESUME);
10073                }
10074            }
10075        } finally {
10076            Binder.restoreCallingIdentity(ident);
10077        }
10078    }
10079
10080    @Override
10081    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10082            Rect tempDockedTaskInsetBounds,
10083            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10084        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10085                "resizeDockedStack()");
10086        long ident = Binder.clearCallingIdentity();
10087        try {
10088            synchronized (this) {
10089                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10090                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10091                        PRESERVE_WINDOWS);
10092            }
10093        } finally {
10094            Binder.restoreCallingIdentity(ident);
10095        }
10096    }
10097
10098    @Override
10099    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10100        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10101                "resizePinnedStack()");
10102        final long ident = Binder.clearCallingIdentity();
10103        try {
10104            synchronized (this) {
10105                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10106            }
10107        } finally {
10108            Binder.restoreCallingIdentity(ident);
10109        }
10110    }
10111
10112    @Override
10113    public void positionTaskInStack(int taskId, int stackId, int position) {
10114        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10115        if (stackId == HOME_STACK_ID) {
10116            throw new IllegalArgumentException(
10117                    "positionTaskInStack: Attempt to change the position of task "
10118                    + taskId + " in/to home stack");
10119        }
10120        synchronized (this) {
10121            long ident = Binder.clearCallingIdentity();
10122            try {
10123                if (DEBUG_STACK) Slog.d(TAG_STACK,
10124                        "positionTaskInStack: positioning task=" + taskId
10125                        + " in stackId=" + stackId + " at position=" + position);
10126                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
10127            } finally {
10128                Binder.restoreCallingIdentity(ident);
10129            }
10130        }
10131    }
10132
10133    @Override
10134    public List<StackInfo> getAllStackInfos() {
10135        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10136        long ident = Binder.clearCallingIdentity();
10137        try {
10138            synchronized (this) {
10139                return mStackSupervisor.getAllStackInfosLocked();
10140            }
10141        } finally {
10142            Binder.restoreCallingIdentity(ident);
10143        }
10144    }
10145
10146    @Override
10147    public StackInfo getStackInfo(int stackId) {
10148        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10149        long ident = Binder.clearCallingIdentity();
10150        try {
10151            synchronized (this) {
10152                return mStackSupervisor.getStackInfoLocked(stackId);
10153            }
10154        } finally {
10155            Binder.restoreCallingIdentity(ident);
10156        }
10157    }
10158
10159    @Override
10160    public boolean isInHomeStack(int taskId) {
10161        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10162        long ident = Binder.clearCallingIdentity();
10163        try {
10164            synchronized (this) {
10165                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10166                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
10167                return tr != null && tr.stack != null && tr.stack.isHomeStack();
10168            }
10169        } finally {
10170            Binder.restoreCallingIdentity(ident);
10171        }
10172    }
10173
10174    @Override
10175    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10176        synchronized(this) {
10177            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10178        }
10179    }
10180
10181    @Override
10182    public void updateDeviceOwner(String packageName) {
10183        final int callingUid = Binder.getCallingUid();
10184        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10185            throw new SecurityException("updateDeviceOwner called from non-system process");
10186        }
10187        synchronized (this) {
10188            mDeviceOwnerName = packageName;
10189        }
10190    }
10191
10192    @Override
10193    public void updateLockTaskPackages(int userId, String[] packages) {
10194        final int callingUid = Binder.getCallingUid();
10195        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10196            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10197                    "updateLockTaskPackages()");
10198        }
10199        synchronized (this) {
10200            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10201                    Arrays.toString(packages));
10202            mLockTaskPackages.put(userId, packages);
10203            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10204        }
10205    }
10206
10207
10208    void startLockTaskModeLocked(TaskRecord task) {
10209        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10210        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10211            return;
10212        }
10213
10214        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10215        // is initiated by system after the pinning request was shown and locked mode is initiated
10216        // by an authorized app directly
10217        final int callingUid = Binder.getCallingUid();
10218        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10219        long ident = Binder.clearCallingIdentity();
10220        try {
10221            if (!isSystemInitiated) {
10222                task.mLockTaskUid = callingUid;
10223                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10224                    // startLockTask() called by app and task mode is lockTaskModeDefault.
10225                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10226                    StatusBarManagerInternal statusBarManager =
10227                            LocalServices.getService(StatusBarManagerInternal.class);
10228                    if (statusBarManager != null) {
10229                        statusBarManager.showScreenPinningRequest(task.taskId);
10230                    }
10231                    return;
10232                }
10233
10234                final ActivityStack stack = mStackSupervisor.getFocusedStack();
10235                if (stack == null || task != stack.topTask()) {
10236                    throw new IllegalArgumentException("Invalid task, not in foreground");
10237                }
10238            }
10239            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10240                    "Locking fully");
10241            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10242                    ActivityManager.LOCK_TASK_MODE_PINNED :
10243                    ActivityManager.LOCK_TASK_MODE_LOCKED,
10244                    "startLockTask", true);
10245        } finally {
10246            Binder.restoreCallingIdentity(ident);
10247        }
10248    }
10249
10250    @Override
10251    public void startLockTaskMode(int taskId) {
10252        synchronized (this) {
10253            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10254            if (task != null) {
10255                startLockTaskModeLocked(task);
10256            }
10257        }
10258    }
10259
10260    @Override
10261    public void startLockTaskMode(IBinder token) {
10262        synchronized (this) {
10263            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10264            if (r == null) {
10265                return;
10266            }
10267            final TaskRecord task = r.task;
10268            if (task != null) {
10269                startLockTaskModeLocked(task);
10270            }
10271        }
10272    }
10273
10274    @Override
10275    public void startSystemLockTaskMode(int taskId) throws RemoteException {
10276        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10277        // This makes inner call to look as if it was initiated by system.
10278        long ident = Binder.clearCallingIdentity();
10279        try {
10280            synchronized (this) {
10281                startLockTaskMode(taskId);
10282            }
10283        } finally {
10284            Binder.restoreCallingIdentity(ident);
10285        }
10286    }
10287
10288    @Override
10289    public void stopLockTaskMode() {
10290        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10291        if (lockTask == null) {
10292            // Our work here is done.
10293            return;
10294        }
10295
10296        final int callingUid = Binder.getCallingUid();
10297        final int lockTaskUid = lockTask.mLockTaskUid;
10298        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10299        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10300            // Done.
10301            return;
10302        } else {
10303            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10304            // It is possible lockTaskMode was started by the system process because
10305            // android:lockTaskMode is set to a locking value in the application manifest
10306            // instead of the app calling startLockTaskMode. In this case
10307            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10308            // {@link TaskRecord.effectiveUid} instead. Also caller with
10309            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10310            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10311                    && callingUid != lockTaskUid
10312                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10313                throw new SecurityException("Invalid uid, expected " + lockTaskUid
10314                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10315            }
10316        }
10317        long ident = Binder.clearCallingIdentity();
10318        try {
10319            Log.d(TAG, "stopLockTaskMode");
10320            // Stop lock task
10321            synchronized (this) {
10322                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10323                        "stopLockTask", true);
10324            }
10325            TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10326            if (tm != null) {
10327                tm.showInCallScreen(false);
10328            }
10329        } finally {
10330            Binder.restoreCallingIdentity(ident);
10331        }
10332    }
10333
10334    /**
10335     * This API should be called by SystemUI only when user perform certain action to dismiss
10336     * lock task mode. We should only dismiss pinned lock task mode in this case.
10337     */
10338    @Override
10339    public void stopSystemLockTaskMode() throws RemoteException {
10340        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10341            stopLockTaskMode();
10342        } else {
10343            mStackSupervisor.showLockTaskToast();
10344        }
10345    }
10346
10347    @Override
10348    public boolean isInLockTaskMode() {
10349        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10350    }
10351
10352    @Override
10353    public int getLockTaskModeState() {
10354        synchronized (this) {
10355            return mStackSupervisor.getLockTaskModeState();
10356        }
10357    }
10358
10359    @Override
10360    public void showLockTaskEscapeMessage(IBinder token) {
10361        synchronized (this) {
10362            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10363            if (r == null) {
10364                return;
10365            }
10366            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10367        }
10368    }
10369
10370    // =========================================================
10371    // CONTENT PROVIDERS
10372    // =========================================================
10373
10374    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10375        List<ProviderInfo> providers = null;
10376        try {
10377            providers = AppGlobals.getPackageManager()
10378                    .queryContentProviders(app.processName, app.uid,
10379                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10380                                    | MATCH_DEBUG_TRIAGED_MISSING)
10381                    .getList();
10382        } catch (RemoteException ex) {
10383        }
10384        if (DEBUG_MU) Slog.v(TAG_MU,
10385                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10386        int userId = app.userId;
10387        if (providers != null) {
10388            int N = providers.size();
10389            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10390            for (int i=0; i<N; i++) {
10391                // TODO: keep logic in sync with installEncryptionUnawareProviders
10392                ProviderInfo cpi =
10393                    (ProviderInfo)providers.get(i);
10394                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10395                        cpi.name, cpi.flags);
10396                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10397                    // This is a singleton provider, but a user besides the
10398                    // default user is asking to initialize a process it runs
10399                    // in...  well, no, it doesn't actually run in this process,
10400                    // it runs in the process of the default user.  Get rid of it.
10401                    providers.remove(i);
10402                    N--;
10403                    i--;
10404                    continue;
10405                }
10406
10407                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10408                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10409                if (cpr == null) {
10410                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10411                    mProviderMap.putProviderByClass(comp, cpr);
10412                }
10413                if (DEBUG_MU) Slog.v(TAG_MU,
10414                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10415                app.pubProviders.put(cpi.name, cpr);
10416                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10417                    // Don't add this if it is a platform component that is marked
10418                    // to run in multiple processes, because this is actually
10419                    // part of the framework so doesn't make sense to track as a
10420                    // separate apk in the process.
10421                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10422                            mProcessStats);
10423                }
10424                notifyPackageUse(cpi.applicationInfo.packageName,
10425                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10426            }
10427        }
10428        return providers;
10429    }
10430
10431    /**
10432     * Check if {@link ProcessRecord} has a possible chance at accessing the
10433     * given {@link ProviderInfo}. Final permission checking is always done
10434     * in {@link ContentProvider}.
10435     */
10436    private final String checkContentProviderPermissionLocked(
10437            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10438        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10439        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10440        boolean checkedGrants = false;
10441        if (checkUser) {
10442            // Looking for cross-user grants before enforcing the typical cross-users permissions
10443            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10444            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10445                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10446                    return null;
10447                }
10448                checkedGrants = true;
10449            }
10450            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10451                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10452            if (userId != tmpTargetUserId) {
10453                // When we actually went to determine the final targer user ID, this ended
10454                // up different than our initial check for the authority.  This is because
10455                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10456                // SELF.  So we need to re-check the grants again.
10457                checkedGrants = false;
10458            }
10459        }
10460        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10461                cpi.applicationInfo.uid, cpi.exported)
10462                == PackageManager.PERMISSION_GRANTED) {
10463            return null;
10464        }
10465        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10466                cpi.applicationInfo.uid, cpi.exported)
10467                == PackageManager.PERMISSION_GRANTED) {
10468            return null;
10469        }
10470
10471        PathPermission[] pps = cpi.pathPermissions;
10472        if (pps != null) {
10473            int i = pps.length;
10474            while (i > 0) {
10475                i--;
10476                PathPermission pp = pps[i];
10477                String pprperm = pp.getReadPermission();
10478                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10479                        cpi.applicationInfo.uid, cpi.exported)
10480                        == PackageManager.PERMISSION_GRANTED) {
10481                    return null;
10482                }
10483                String ppwperm = pp.getWritePermission();
10484                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10485                        cpi.applicationInfo.uid, cpi.exported)
10486                        == PackageManager.PERMISSION_GRANTED) {
10487                    return null;
10488                }
10489            }
10490        }
10491        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10492            return null;
10493        }
10494
10495        String msg;
10496        if (!cpi.exported) {
10497            msg = "Permission Denial: opening provider " + cpi.name
10498                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10499                    + ", uid=" + callingUid + ") that is not exported from uid "
10500                    + cpi.applicationInfo.uid;
10501        } else {
10502            msg = "Permission Denial: opening provider " + cpi.name
10503                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10504                    + ", uid=" + callingUid + ") requires "
10505                    + cpi.readPermission + " or " + cpi.writePermission;
10506        }
10507        Slog.w(TAG, msg);
10508        return msg;
10509    }
10510
10511    /**
10512     * Returns if the ContentProvider has granted a uri to callingUid
10513     */
10514    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10515        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10516        if (perms != null) {
10517            for (int i=perms.size()-1; i>=0; i--) {
10518                GrantUri grantUri = perms.keyAt(i);
10519                if (grantUri.sourceUserId == userId || !checkUser) {
10520                    if (matchesProvider(grantUri.uri, cpi)) {
10521                        return true;
10522                    }
10523                }
10524            }
10525        }
10526        return false;
10527    }
10528
10529    /**
10530     * Returns true if the uri authority is one of the authorities specified in the provider.
10531     */
10532    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10533        String uriAuth = uri.getAuthority();
10534        String cpiAuth = cpi.authority;
10535        if (cpiAuth.indexOf(';') == -1) {
10536            return cpiAuth.equals(uriAuth);
10537        }
10538        String[] cpiAuths = cpiAuth.split(";");
10539        int length = cpiAuths.length;
10540        for (int i = 0; i < length; i++) {
10541            if (cpiAuths[i].equals(uriAuth)) return true;
10542        }
10543        return false;
10544    }
10545
10546    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10547            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10548        if (r != null) {
10549            for (int i=0; i<r.conProviders.size(); i++) {
10550                ContentProviderConnection conn = r.conProviders.get(i);
10551                if (conn.provider == cpr) {
10552                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10553                            "Adding provider requested by "
10554                            + r.processName + " from process "
10555                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10556                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10557                    if (stable) {
10558                        conn.stableCount++;
10559                        conn.numStableIncs++;
10560                    } else {
10561                        conn.unstableCount++;
10562                        conn.numUnstableIncs++;
10563                    }
10564                    return conn;
10565                }
10566            }
10567            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10568            if (stable) {
10569                conn.stableCount = 1;
10570                conn.numStableIncs = 1;
10571            } else {
10572                conn.unstableCount = 1;
10573                conn.numUnstableIncs = 1;
10574            }
10575            cpr.connections.add(conn);
10576            r.conProviders.add(conn);
10577            startAssociationLocked(r.uid, r.processName, r.curProcState,
10578                    cpr.uid, cpr.name, cpr.info.processName);
10579            return conn;
10580        }
10581        cpr.addExternalProcessHandleLocked(externalProcessToken);
10582        return null;
10583    }
10584
10585    boolean decProviderCountLocked(ContentProviderConnection conn,
10586            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10587        if (conn != null) {
10588            cpr = conn.provider;
10589            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10590                    "Removing provider requested by "
10591                    + conn.client.processName + " from process "
10592                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10593                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10594            if (stable) {
10595                conn.stableCount--;
10596            } else {
10597                conn.unstableCount--;
10598            }
10599            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10600                cpr.connections.remove(conn);
10601                conn.client.conProviders.remove(conn);
10602                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10603                    // The client is more important than last activity -- note the time this
10604                    // is happening, so we keep the old provider process around a bit as last
10605                    // activity to avoid thrashing it.
10606                    if (cpr.proc != null) {
10607                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10608                    }
10609                }
10610                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10611                return true;
10612            }
10613            return false;
10614        }
10615        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10616        return false;
10617    }
10618
10619    private void checkTime(long startTime, String where) {
10620        long now = SystemClock.uptimeMillis();
10621        if ((now-startTime) > 50) {
10622            // If we are taking more than 50ms, log about it.
10623            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10624        }
10625    }
10626
10627    private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
10628            PROC_SPACE_TERM,
10629            PROC_SPACE_TERM|PROC_PARENS,
10630            PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
10631    };
10632
10633    private final long[] mProcessStateStatsLongs = new long[1];
10634
10635    boolean isProcessAliveLocked(ProcessRecord proc) {
10636        if (proc.procStatFile == null) {
10637            proc.procStatFile = "/proc/" + proc.pid + "/stat";
10638        }
10639        mProcessStateStatsLongs[0] = 0;
10640        if (!Process.readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
10641                mProcessStateStatsLongs, null)) {
10642            if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
10643            return false;
10644        }
10645        final long state = mProcessStateStatsLongs[0];
10646        if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
10647                + (char)state);
10648        return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
10649    }
10650
10651    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10652            String name, IBinder token, boolean stable, int userId) {
10653        ContentProviderRecord cpr;
10654        ContentProviderConnection conn = null;
10655        ProviderInfo cpi = null;
10656
10657        synchronized(this) {
10658            long startTime = SystemClock.uptimeMillis();
10659
10660            ProcessRecord r = null;
10661            if (caller != null) {
10662                r = getRecordForAppLocked(caller);
10663                if (r == null) {
10664                    throw new SecurityException(
10665                            "Unable to find app for caller " + caller
10666                          + " (pid=" + Binder.getCallingPid()
10667                          + ") when getting content provider " + name);
10668                }
10669            }
10670
10671            boolean checkCrossUser = true;
10672
10673            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10674
10675            // First check if this content provider has been published...
10676            cpr = mProviderMap.getProviderByName(name, userId);
10677            // If that didn't work, check if it exists for user 0 and then
10678            // verify that it's a singleton provider before using it.
10679            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10680                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10681                if (cpr != null) {
10682                    cpi = cpr.info;
10683                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10684                            cpi.name, cpi.flags)
10685                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10686                        userId = UserHandle.USER_SYSTEM;
10687                        checkCrossUser = false;
10688                    } else {
10689                        cpr = null;
10690                        cpi = null;
10691                    }
10692                }
10693            }
10694
10695            boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
10696            if (providerRunning) {
10697                cpi = cpr.info;
10698                String msg;
10699                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10700                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10701                        != null) {
10702                    throw new SecurityException(msg);
10703                }
10704                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10705
10706                if (r != null && cpr.canRunHere(r)) {
10707                    // This provider has been published or is in the process
10708                    // of being published...  but it is also allowed to run
10709                    // in the caller's process, so don't make a connection
10710                    // and just let the caller instantiate its own instance.
10711                    ContentProviderHolder holder = cpr.newHolder(null);
10712                    // don't give caller the provider object, it needs
10713                    // to make its own.
10714                    holder.provider = null;
10715                    return holder;
10716                }
10717
10718                final long origId = Binder.clearCallingIdentity();
10719
10720                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10721
10722                // In this case the provider instance already exists, so we can
10723                // return it right away.
10724                conn = incProviderCountLocked(r, cpr, token, stable);
10725                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10726                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10727                        // If this is a perceptible app accessing the provider,
10728                        // make sure to count it as being accessed and thus
10729                        // back up on the LRU list.  This is good because
10730                        // content providers are often expensive to start.
10731                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10732                        updateLruProcessLocked(cpr.proc, false, null);
10733                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10734                    }
10735                }
10736
10737                checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10738                final int verifiedAdj = cpr.proc.verifiedAdj;
10739                boolean success = updateOomAdjLocked(cpr.proc);
10740                // XXX things have changed so updateOomAdjLocked doesn't actually tell us
10741                // if the process has been successfully adjusted.  So to reduce races with
10742                // it, we will check whether the process still exists.  Note that this doesn't
10743                // completely get rid of races with LMK killing the process, but should make
10744                // them much smaller.
10745                if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
10746                    success = false;
10747                }
10748                maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10749                checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10750                if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10751                // NOTE: there is still a race here where a signal could be
10752                // pending on the process even though we managed to update its
10753                // adj level.  Not sure what to do about this, but at least
10754                // the race is now smaller.
10755                if (!success) {
10756                    // Uh oh...  it looks like the provider's process
10757                    // has been killed on us.  We need to wait for a new
10758                    // process to be started, and make sure its death
10759                    // doesn't kill our process.
10760                    Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10761                            + " is crashing; detaching " + r);
10762                    boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10763                    checkTime(startTime, "getContentProviderImpl: before appDied");
10764                    appDiedLocked(cpr.proc);
10765                    checkTime(startTime, "getContentProviderImpl: after appDied");
10766                    if (!lastRef) {
10767                        // This wasn't the last ref our process had on
10768                        // the provider...  we have now been killed, bail.
10769                        return null;
10770                    }
10771                    providerRunning = false;
10772                    conn = null;
10773                } else {
10774                    cpr.proc.verifiedAdj = cpr.proc.setAdj;
10775                }
10776
10777                Binder.restoreCallingIdentity(origId);
10778            }
10779
10780            if (!providerRunning) {
10781                try {
10782                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10783                    cpi = AppGlobals.getPackageManager().
10784                        resolveContentProvider(name,
10785                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10786                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10787                } catch (RemoteException ex) {
10788                }
10789                if (cpi == null) {
10790                    return null;
10791                }
10792                // If the provider is a singleton AND
10793                // (it's a call within the same user || the provider is a
10794                // privileged app)
10795                // Then allow connecting to the singleton provider
10796                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10797                        cpi.name, cpi.flags)
10798                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10799                if (singleton) {
10800                    userId = UserHandle.USER_SYSTEM;
10801                }
10802                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10803                checkTime(startTime, "getContentProviderImpl: got app info for user");
10804
10805                String msg;
10806                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10807                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10808                        != null) {
10809                    throw new SecurityException(msg);
10810                }
10811                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10812
10813                if (!mProcessesReady
10814                        && !cpi.processName.equals("system")) {
10815                    // If this content provider does not run in the system
10816                    // process, and the system is not yet ready to run other
10817                    // processes, then fail fast instead of hanging.
10818                    throw new IllegalArgumentException(
10819                            "Attempt to launch content provider before system ready");
10820                }
10821
10822                // Make sure that the user who owns this provider is running.  If not,
10823                // we don't want to allow it to run.
10824                if (!mUserController.isUserRunningLocked(userId, 0)) {
10825                    Slog.w(TAG, "Unable to launch app "
10826                            + cpi.applicationInfo.packageName + "/"
10827                            + cpi.applicationInfo.uid + " for provider "
10828                            + name + ": user " + userId + " is stopped");
10829                    return null;
10830                }
10831
10832                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10833                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10834                cpr = mProviderMap.getProviderByClass(comp, userId);
10835                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10836                final boolean firstClass = cpr == null;
10837                if (firstClass) {
10838                    final long ident = Binder.clearCallingIdentity();
10839
10840                    // If permissions need a review before any of the app components can run,
10841                    // we return no provider and launch a review activity if the calling app
10842                    // is in the foreground.
10843                    if (mPermissionReviewRequired || Build.PERMISSIONS_REVIEW_REQUIRED) {
10844                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10845                            return null;
10846                        }
10847                    }
10848
10849                    try {
10850                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10851                        ApplicationInfo ai =
10852                            AppGlobals.getPackageManager().
10853                                getApplicationInfo(
10854                                        cpi.applicationInfo.packageName,
10855                                        STOCK_PM_FLAGS, userId);
10856                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10857                        if (ai == null) {
10858                            Slog.w(TAG, "No package info for content provider "
10859                                    + cpi.name);
10860                            return null;
10861                        }
10862                        ai = getAppInfoForUser(ai, userId);
10863                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10864                    } catch (RemoteException ex) {
10865                        // pm is in same process, this will never happen.
10866                    } finally {
10867                        Binder.restoreCallingIdentity(ident);
10868                    }
10869                }
10870
10871                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10872
10873                if (r != null && cpr.canRunHere(r)) {
10874                    // If this is a multiprocess provider, then just return its
10875                    // info and allow the caller to instantiate it.  Only do
10876                    // this if the provider is the same user as the caller's
10877                    // process, or can run as root (so can be in any process).
10878                    return cpr.newHolder(null);
10879                }
10880
10881                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10882                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10883                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10884
10885                // This is single process, and our app is now connecting to it.
10886                // See if we are already in the process of launching this
10887                // provider.
10888                final int N = mLaunchingProviders.size();
10889                int i;
10890                for (i = 0; i < N; i++) {
10891                    if (mLaunchingProviders.get(i) == cpr) {
10892                        break;
10893                    }
10894                }
10895
10896                // If the provider is not already being launched, then get it
10897                // started.
10898                if (i >= N) {
10899                    final long origId = Binder.clearCallingIdentity();
10900
10901                    try {
10902                        // Content provider is now in use, its package can't be stopped.
10903                        try {
10904                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10905                            AppGlobals.getPackageManager().setPackageStoppedState(
10906                                    cpr.appInfo.packageName, false, userId);
10907                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10908                        } catch (RemoteException e) {
10909                        } catch (IllegalArgumentException e) {
10910                            Slog.w(TAG, "Failed trying to unstop package "
10911                                    + cpr.appInfo.packageName + ": " + e);
10912                        }
10913
10914                        // Use existing process if already started
10915                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10916                        ProcessRecord proc = getProcessRecordLocked(
10917                                cpi.processName, cpr.appInfo.uid, false);
10918                        if (proc != null && proc.thread != null && !proc.killed) {
10919                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10920                                    "Installing in existing process " + proc);
10921                            if (!proc.pubProviders.containsKey(cpi.name)) {
10922                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10923                                proc.pubProviders.put(cpi.name, cpr);
10924                                try {
10925                                    proc.thread.scheduleInstallProvider(cpi);
10926                                } catch (RemoteException e) {
10927                                }
10928                            }
10929                        } else {
10930                            checkTime(startTime, "getContentProviderImpl: before start process");
10931                            proc = startProcessLocked(cpi.processName,
10932                                    cpr.appInfo, false, 0, "content provider",
10933                                    new ComponentName(cpi.applicationInfo.packageName,
10934                                            cpi.name), false, false, false);
10935                            checkTime(startTime, "getContentProviderImpl: after start process");
10936                            if (proc == null) {
10937                                Slog.w(TAG, "Unable to launch app "
10938                                        + cpi.applicationInfo.packageName + "/"
10939                                        + cpi.applicationInfo.uid + " for provider "
10940                                        + name + ": process is bad");
10941                                return null;
10942                            }
10943                        }
10944                        cpr.launchingApp = proc;
10945                        mLaunchingProviders.add(cpr);
10946                    } finally {
10947                        Binder.restoreCallingIdentity(origId);
10948                    }
10949                }
10950
10951                checkTime(startTime, "getContentProviderImpl: updating data structures");
10952
10953                // Make sure the provider is published (the same provider class
10954                // may be published under multiple names).
10955                if (firstClass) {
10956                    mProviderMap.putProviderByClass(comp, cpr);
10957                }
10958
10959                mProviderMap.putProviderByName(name, cpr);
10960                conn = incProviderCountLocked(r, cpr, token, stable);
10961                if (conn != null) {
10962                    conn.waiting = true;
10963                }
10964            }
10965            checkTime(startTime, "getContentProviderImpl: done!");
10966        }
10967
10968        // Wait for the provider to be published...
10969        synchronized (cpr) {
10970            while (cpr.provider == null) {
10971                if (cpr.launchingApp == null) {
10972                    Slog.w(TAG, "Unable to launch app "
10973                            + cpi.applicationInfo.packageName + "/"
10974                            + cpi.applicationInfo.uid + " for provider "
10975                            + name + ": launching app became null");
10976                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10977                            UserHandle.getUserId(cpi.applicationInfo.uid),
10978                            cpi.applicationInfo.packageName,
10979                            cpi.applicationInfo.uid, name);
10980                    return null;
10981                }
10982                try {
10983                    if (DEBUG_MU) Slog.v(TAG_MU,
10984                            "Waiting to start provider " + cpr
10985                            + " launchingApp=" + cpr.launchingApp);
10986                    if (conn != null) {
10987                        conn.waiting = true;
10988                    }
10989                    cpr.wait();
10990                } catch (InterruptedException ex) {
10991                } finally {
10992                    if (conn != null) {
10993                        conn.waiting = false;
10994                    }
10995                }
10996            }
10997        }
10998        return cpr != null ? cpr.newHolder(conn) : null;
10999    }
11000
11001    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
11002            ProcessRecord r, final int userId) {
11003        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
11004                cpi.packageName, userId)) {
11005
11006            final boolean callerForeground = r == null || r.setSchedGroup
11007                    != ProcessList.SCHED_GROUP_BACKGROUND;
11008
11009            // Show a permission review UI only for starting from a foreground app
11010            if (!callerForeground) {
11011                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
11012                        + cpi.packageName + " requires a permissions review");
11013                return false;
11014            }
11015
11016            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
11017            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11018                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
11019            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
11020
11021            if (DEBUG_PERMISSIONS_REVIEW) {
11022                Slog.i(TAG, "u" + userId + " Launching permission review "
11023                        + "for package " + cpi.packageName);
11024            }
11025
11026            final UserHandle userHandle = new UserHandle(userId);
11027            mHandler.post(new Runnable() {
11028                @Override
11029                public void run() {
11030                    mContext.startActivityAsUser(intent, userHandle);
11031                }
11032            });
11033
11034            return false;
11035        }
11036
11037        return true;
11038    }
11039
11040    PackageManagerInternal getPackageManagerInternalLocked() {
11041        if (mPackageManagerInt == null) {
11042            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
11043        }
11044        return mPackageManagerInt;
11045    }
11046
11047    @Override
11048    public final ContentProviderHolder getContentProvider(
11049            IApplicationThread caller, String name, int userId, boolean stable) {
11050        enforceNotIsolatedCaller("getContentProvider");
11051        if (caller == null) {
11052            String msg = "null IApplicationThread when getting content provider "
11053                    + name;
11054            Slog.w(TAG, msg);
11055            throw new SecurityException(msg);
11056        }
11057        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
11058        // with cross-user grant.
11059        return getContentProviderImpl(caller, name, null, stable, userId);
11060    }
11061
11062    public ContentProviderHolder getContentProviderExternal(
11063            String name, int userId, IBinder token) {
11064        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11065            "Do not have permission in call getContentProviderExternal()");
11066        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
11067                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
11068        return getContentProviderExternalUnchecked(name, token, userId);
11069    }
11070
11071    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
11072            IBinder token, int userId) {
11073        return getContentProviderImpl(null, name, token, true, userId);
11074    }
11075
11076    /**
11077     * Drop a content provider from a ProcessRecord's bookkeeping
11078     */
11079    public void removeContentProvider(IBinder connection, boolean stable) {
11080        enforceNotIsolatedCaller("removeContentProvider");
11081        long ident = Binder.clearCallingIdentity();
11082        try {
11083            synchronized (this) {
11084                ContentProviderConnection conn;
11085                try {
11086                    conn = (ContentProviderConnection)connection;
11087                } catch (ClassCastException e) {
11088                    String msg ="removeContentProvider: " + connection
11089                            + " not a ContentProviderConnection";
11090                    Slog.w(TAG, msg);
11091                    throw new IllegalArgumentException(msg);
11092                }
11093                if (conn == null) {
11094                    throw new NullPointerException("connection is null");
11095                }
11096                if (decProviderCountLocked(conn, null, null, stable)) {
11097                    updateOomAdjLocked();
11098                }
11099            }
11100        } finally {
11101            Binder.restoreCallingIdentity(ident);
11102        }
11103    }
11104
11105    public void removeContentProviderExternal(String name, IBinder token) {
11106        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11107            "Do not have permission in call removeContentProviderExternal()");
11108        int userId = UserHandle.getCallingUserId();
11109        long ident = Binder.clearCallingIdentity();
11110        try {
11111            removeContentProviderExternalUnchecked(name, token, userId);
11112        } finally {
11113            Binder.restoreCallingIdentity(ident);
11114        }
11115    }
11116
11117    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11118        synchronized (this) {
11119            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11120            if(cpr == null) {
11121                //remove from mProvidersByClass
11122                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11123                return;
11124            }
11125
11126            //update content provider record entry info
11127            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11128            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11129            if (localCpr.hasExternalProcessHandles()) {
11130                if (localCpr.removeExternalProcessHandleLocked(token)) {
11131                    updateOomAdjLocked();
11132                } else {
11133                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11134                            + " with no external reference for token: "
11135                            + token + ".");
11136                }
11137            } else {
11138                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11139                        + " with no external references.");
11140            }
11141        }
11142    }
11143
11144    public final void publishContentProviders(IApplicationThread caller,
11145            List<ContentProviderHolder> providers) {
11146        if (providers == null) {
11147            return;
11148        }
11149
11150        enforceNotIsolatedCaller("publishContentProviders");
11151        synchronized (this) {
11152            final ProcessRecord r = getRecordForAppLocked(caller);
11153            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11154            if (r == null) {
11155                throw new SecurityException(
11156                        "Unable to find app for caller " + caller
11157                      + " (pid=" + Binder.getCallingPid()
11158                      + ") when publishing content providers");
11159            }
11160
11161            final long origId = Binder.clearCallingIdentity();
11162
11163            final int N = providers.size();
11164            for (int i = 0; i < N; i++) {
11165                ContentProviderHolder src = providers.get(i);
11166                if (src == null || src.info == null || src.provider == null) {
11167                    continue;
11168                }
11169                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11170                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11171                if (dst != null) {
11172                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11173                    mProviderMap.putProviderByClass(comp, dst);
11174                    String names[] = dst.info.authority.split(";");
11175                    for (int j = 0; j < names.length; j++) {
11176                        mProviderMap.putProviderByName(names[j], dst);
11177                    }
11178
11179                    int launchingCount = mLaunchingProviders.size();
11180                    int j;
11181                    boolean wasInLaunchingProviders = false;
11182                    for (j = 0; j < launchingCount; j++) {
11183                        if (mLaunchingProviders.get(j) == dst) {
11184                            mLaunchingProviders.remove(j);
11185                            wasInLaunchingProviders = true;
11186                            j--;
11187                            launchingCount--;
11188                        }
11189                    }
11190                    if (wasInLaunchingProviders) {
11191                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11192                    }
11193                    synchronized (dst) {
11194                        dst.provider = src.provider;
11195                        dst.proc = r;
11196                        dst.notifyAll();
11197                    }
11198                    updateOomAdjLocked(r);
11199                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11200                            src.info.authority);
11201                }
11202            }
11203
11204            Binder.restoreCallingIdentity(origId);
11205        }
11206    }
11207
11208    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11209        ContentProviderConnection conn;
11210        try {
11211            conn = (ContentProviderConnection)connection;
11212        } catch (ClassCastException e) {
11213            String msg ="refContentProvider: " + connection
11214                    + " not a ContentProviderConnection";
11215            Slog.w(TAG, msg);
11216            throw new IllegalArgumentException(msg);
11217        }
11218        if (conn == null) {
11219            throw new NullPointerException("connection is null");
11220        }
11221
11222        synchronized (this) {
11223            if (stable > 0) {
11224                conn.numStableIncs += stable;
11225            }
11226            stable = conn.stableCount + stable;
11227            if (stable < 0) {
11228                throw new IllegalStateException("stableCount < 0: " + stable);
11229            }
11230
11231            if (unstable > 0) {
11232                conn.numUnstableIncs += unstable;
11233            }
11234            unstable = conn.unstableCount + unstable;
11235            if (unstable < 0) {
11236                throw new IllegalStateException("unstableCount < 0: " + unstable);
11237            }
11238
11239            if ((stable+unstable) <= 0) {
11240                throw new IllegalStateException("ref counts can't go to zero here: stable="
11241                        + stable + " unstable=" + unstable);
11242            }
11243            conn.stableCount = stable;
11244            conn.unstableCount = unstable;
11245            return !conn.dead;
11246        }
11247    }
11248
11249    public void unstableProviderDied(IBinder connection) {
11250        ContentProviderConnection conn;
11251        try {
11252            conn = (ContentProviderConnection)connection;
11253        } catch (ClassCastException e) {
11254            String msg ="refContentProvider: " + connection
11255                    + " not a ContentProviderConnection";
11256            Slog.w(TAG, msg);
11257            throw new IllegalArgumentException(msg);
11258        }
11259        if (conn == null) {
11260            throw new NullPointerException("connection is null");
11261        }
11262
11263        // Safely retrieve the content provider associated with the connection.
11264        IContentProvider provider;
11265        synchronized (this) {
11266            provider = conn.provider.provider;
11267        }
11268
11269        if (provider == null) {
11270            // Um, yeah, we're way ahead of you.
11271            return;
11272        }
11273
11274        // Make sure the caller is being honest with us.
11275        if (provider.asBinder().pingBinder()) {
11276            // Er, no, still looks good to us.
11277            synchronized (this) {
11278                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11279                        + " says " + conn + " died, but we don't agree");
11280                return;
11281            }
11282        }
11283
11284        // Well look at that!  It's dead!
11285        synchronized (this) {
11286            if (conn.provider.provider != provider) {
11287                // But something changed...  good enough.
11288                return;
11289            }
11290
11291            ProcessRecord proc = conn.provider.proc;
11292            if (proc == null || proc.thread == null) {
11293                // Seems like the process is already cleaned up.
11294                return;
11295            }
11296
11297            // As far as we're concerned, this is just like receiving a
11298            // death notification...  just a bit prematurely.
11299            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11300                    + ") early provider death");
11301            final long ident = Binder.clearCallingIdentity();
11302            try {
11303                appDiedLocked(proc);
11304            } finally {
11305                Binder.restoreCallingIdentity(ident);
11306            }
11307        }
11308    }
11309
11310    @Override
11311    public void appNotRespondingViaProvider(IBinder connection) {
11312        enforceCallingPermission(
11313                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11314
11315        final ContentProviderConnection conn = (ContentProviderConnection) connection;
11316        if (conn == null) {
11317            Slog.w(TAG, "ContentProviderConnection is null");
11318            return;
11319        }
11320
11321        final ProcessRecord host = conn.provider.proc;
11322        if (host == null) {
11323            Slog.w(TAG, "Failed to find hosting ProcessRecord");
11324            return;
11325        }
11326
11327        mHandler.post(new Runnable() {
11328            @Override
11329            public void run() {
11330                mAppErrors.appNotResponding(host, null, null, false,
11331                        "ContentProvider not responding");
11332            }
11333        });
11334    }
11335
11336    public final void installSystemProviders() {
11337        List<ProviderInfo> providers;
11338        synchronized (this) {
11339            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11340            providers = generateApplicationProvidersLocked(app);
11341            if (providers != null) {
11342                for (int i=providers.size()-1; i>=0; i--) {
11343                    ProviderInfo pi = (ProviderInfo)providers.get(i);
11344                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11345                        Slog.w(TAG, "Not installing system proc provider " + pi.name
11346                                + ": not system .apk");
11347                        providers.remove(i);
11348                    }
11349                }
11350            }
11351        }
11352        if (providers != null) {
11353            mSystemThread.installSystemProviders(providers);
11354        }
11355
11356        mCoreSettingsObserver = new CoreSettingsObserver(this);
11357        mFontScaleSettingObserver = new FontScaleSettingObserver();
11358
11359        //mUsageStatsService.monitorPackages();
11360    }
11361
11362    private void startPersistentApps(int matchFlags) {
11363        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11364
11365        synchronized (this) {
11366            try {
11367                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11368                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11369                for (ApplicationInfo app : apps) {
11370                    if (!"android".equals(app.packageName)) {
11371                        addAppLocked(app, false, null /* ABI override */);
11372                    }
11373                }
11374            } catch (RemoteException ex) {
11375            }
11376        }
11377    }
11378
11379    /**
11380     * When a user is unlocked, we need to install encryption-unaware providers
11381     * belonging to any running apps.
11382     */
11383    private void installEncryptionUnawareProviders(int userId) {
11384        // We're only interested in providers that are encryption unaware, and
11385        // we don't care about uninstalled apps, since there's no way they're
11386        // running at this point.
11387        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11388
11389        synchronized (this) {
11390            final int NP = mProcessNames.getMap().size();
11391            for (int ip = 0; ip < NP; ip++) {
11392                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11393                final int NA = apps.size();
11394                for (int ia = 0; ia < NA; ia++) {
11395                    final ProcessRecord app = apps.valueAt(ia);
11396                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11397
11398                    final int NG = app.pkgList.size();
11399                    for (int ig = 0; ig < NG; ig++) {
11400                        try {
11401                            final String pkgName = app.pkgList.keyAt(ig);
11402                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11403                                    .getPackageInfo(pkgName, matchFlags, userId);
11404                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11405                                for (ProviderInfo pi : pkgInfo.providers) {
11406                                    // TODO: keep in sync with generateApplicationProvidersLocked
11407                                    final boolean processMatch = Objects.equals(pi.processName,
11408                                            app.processName) || pi.multiprocess;
11409                                    final boolean userMatch = isSingleton(pi.processName,
11410                                            pi.applicationInfo, pi.name, pi.flags)
11411                                                    ? (app.userId == UserHandle.USER_SYSTEM) : true;
11412                                    if (processMatch && userMatch) {
11413                                        Log.v(TAG, "Installing " + pi);
11414                                        app.thread.scheduleInstallProvider(pi);
11415                                    } else {
11416                                        Log.v(TAG, "Skipping " + pi);
11417                                    }
11418                                }
11419                            }
11420                        } catch (RemoteException ignored) {
11421                        }
11422                    }
11423                }
11424            }
11425        }
11426    }
11427
11428    /**
11429     * Allows apps to retrieve the MIME type of a URI.
11430     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11431     * users, then it does not need permission to access the ContentProvider.
11432     * Either, it needs cross-user uri grants.
11433     *
11434     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11435     *
11436     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11437     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11438     */
11439    public String getProviderMimeType(Uri uri, int userId) {
11440        enforceNotIsolatedCaller("getProviderMimeType");
11441        final String name = uri.getAuthority();
11442        int callingUid = Binder.getCallingUid();
11443        int callingPid = Binder.getCallingPid();
11444        long ident = 0;
11445        boolean clearedIdentity = false;
11446        synchronized (this) {
11447            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11448        }
11449        if (canClearIdentity(callingPid, callingUid, userId)) {
11450            clearedIdentity = true;
11451            ident = Binder.clearCallingIdentity();
11452        }
11453        ContentProviderHolder holder = null;
11454        try {
11455            holder = getContentProviderExternalUnchecked(name, null, userId);
11456            if (holder != null) {
11457                return holder.provider.getType(uri);
11458            }
11459        } catch (RemoteException e) {
11460            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11461            return null;
11462        } catch (Exception e) {
11463            Log.w(TAG, "Exception while determining type of " + uri, e);
11464            return null;
11465        } finally {
11466            // We need to clear the identity to call removeContentProviderExternalUnchecked
11467            if (!clearedIdentity) {
11468                ident = Binder.clearCallingIdentity();
11469            }
11470            try {
11471                if (holder != null) {
11472                    removeContentProviderExternalUnchecked(name, null, userId);
11473                }
11474            } finally {
11475                Binder.restoreCallingIdentity(ident);
11476            }
11477        }
11478
11479        return null;
11480    }
11481
11482    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11483        if (UserHandle.getUserId(callingUid) == userId) {
11484            return true;
11485        }
11486        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11487                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11488                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11489                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11490                return true;
11491        }
11492        return false;
11493    }
11494
11495    // =========================================================
11496    // GLOBAL MANAGEMENT
11497    // =========================================================
11498
11499    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11500            boolean isolated, int isolatedUid) {
11501        String proc = customProcess != null ? customProcess : info.processName;
11502        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11503        final int userId = UserHandle.getUserId(info.uid);
11504        int uid = info.uid;
11505        if (isolated) {
11506            if (isolatedUid == 0) {
11507                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11508                while (true) {
11509                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11510                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11511                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11512                    }
11513                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11514                    mNextIsolatedProcessUid++;
11515                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11516                        // No process for this uid, use it.
11517                        break;
11518                    }
11519                    stepsLeft--;
11520                    if (stepsLeft <= 0) {
11521                        return null;
11522                    }
11523                }
11524            } else {
11525                // Special case for startIsolatedProcess (internal only), where
11526                // the uid of the isolated process is specified by the caller.
11527                uid = isolatedUid;
11528            }
11529
11530            // Register the isolated UID with this application so BatteryStats knows to
11531            // attribute resource usage to the application.
11532            //
11533            // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
11534            // about the process state of the isolated UID *before* it is registered with the
11535            // owning application.
11536            mBatteryStatsService.addIsolatedUid(uid, info.uid);
11537        }
11538        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11539        if (!mBooted && !mBooting
11540                && userId == UserHandle.USER_SYSTEM
11541                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11542            r.persistent = true;
11543            r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11544        }
11545        addProcessNameLocked(r);
11546        return r;
11547    }
11548
11549    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11550            String abiOverride) {
11551        ProcessRecord app;
11552        if (!isolated) {
11553            app = getProcessRecordLocked(info.processName, info.uid, true);
11554        } else {
11555            app = null;
11556        }
11557
11558        if (app == null) {
11559            app = newProcessRecordLocked(info, null, isolated, 0);
11560            updateLruProcessLocked(app, false, null);
11561            updateOomAdjLocked();
11562        }
11563
11564        // This package really, really can not be stopped.
11565        try {
11566            AppGlobals.getPackageManager().setPackageStoppedState(
11567                    info.packageName, false, UserHandle.getUserId(app.uid));
11568        } catch (RemoteException e) {
11569        } catch (IllegalArgumentException e) {
11570            Slog.w(TAG, "Failed trying to unstop package "
11571                    + info.packageName + ": " + e);
11572        }
11573
11574        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11575            app.persistent = true;
11576            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11577        }
11578        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11579            mPersistentStartingProcesses.add(app);
11580            startProcessLocked(app, "added application", app.processName, abiOverride,
11581                    null /* entryPoint */, null /* entryPointArgs */);
11582        }
11583
11584        return app;
11585    }
11586
11587    public void unhandledBack() {
11588        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11589                "unhandledBack()");
11590
11591        synchronized(this) {
11592            final long origId = Binder.clearCallingIdentity();
11593            try {
11594                getFocusedStack().unhandledBackLocked();
11595            } finally {
11596                Binder.restoreCallingIdentity(origId);
11597            }
11598        }
11599    }
11600
11601    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11602        enforceNotIsolatedCaller("openContentUri");
11603        final int userId = UserHandle.getCallingUserId();
11604        String name = uri.getAuthority();
11605        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11606        ParcelFileDescriptor pfd = null;
11607        if (cph != null) {
11608            // We record the binder invoker's uid in thread-local storage before
11609            // going to the content provider to open the file.  Later, in the code
11610            // that handles all permissions checks, we look for this uid and use
11611            // that rather than the Activity Manager's own uid.  The effect is that
11612            // we do the check against the caller's permissions even though it looks
11613            // to the content provider like the Activity Manager itself is making
11614            // the request.
11615            Binder token = new Binder();
11616            sCallerIdentity.set(new Identity(
11617                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11618            try {
11619                pfd = cph.provider.openFile(null, uri, "r", null, token);
11620            } catch (FileNotFoundException e) {
11621                // do nothing; pfd will be returned null
11622            } finally {
11623                // Ensure that whatever happens, we clean up the identity state
11624                sCallerIdentity.remove();
11625                // Ensure we're done with the provider.
11626                removeContentProviderExternalUnchecked(name, null, userId);
11627            }
11628        } else {
11629            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11630        }
11631        return pfd;
11632    }
11633
11634    // Actually is sleeping or shutting down or whatever else in the future
11635    // is an inactive state.
11636    boolean isSleepingOrShuttingDownLocked() {
11637        return isSleepingLocked() || mShuttingDown;
11638    }
11639
11640    boolean isShuttingDownLocked() {
11641        return mShuttingDown;
11642    }
11643
11644    boolean isSleepingLocked() {
11645        return mSleeping;
11646    }
11647
11648    void onWakefulnessChanged(int wakefulness) {
11649        synchronized(this) {
11650            mWakefulness = wakefulness;
11651            updateSleepIfNeededLocked();
11652        }
11653    }
11654
11655    void finishRunningVoiceLocked() {
11656        if (mRunningVoice != null) {
11657            mRunningVoice = null;
11658            mVoiceWakeLock.release();
11659            updateSleepIfNeededLocked();
11660        }
11661    }
11662
11663    void startTimeTrackingFocusedActivityLocked() {
11664        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11665            mCurAppTimeTracker.start(mFocusedActivity.packageName);
11666        }
11667    }
11668
11669    void updateSleepIfNeededLocked() {
11670        if (mSleeping && !shouldSleepLocked()) {
11671            mSleeping = false;
11672            startTimeTrackingFocusedActivityLocked();
11673            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11674            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11675            updateOomAdjLocked();
11676        } else if (!mSleeping && shouldSleepLocked()) {
11677            mSleeping = true;
11678            if (mCurAppTimeTracker != null) {
11679                mCurAppTimeTracker.stop();
11680            }
11681            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11682            mStackSupervisor.goingToSleepLocked();
11683            updateOomAdjLocked();
11684
11685            // Initialize the wake times of all processes.
11686            checkExcessivePowerUsageLocked(false);
11687            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11688            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11689            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11690        }
11691    }
11692
11693    private boolean shouldSleepLocked() {
11694        // Resume applications while running a voice interactor.
11695        if (mRunningVoice != null) {
11696            return false;
11697        }
11698
11699        // TODO: Transform the lock screen state into a sleep token instead.
11700        switch (mWakefulness) {
11701            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11702            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11703            case PowerManagerInternal.WAKEFULNESS_DOZING:
11704                // Pause applications whenever the lock screen is shown or any sleep
11705                // tokens have been acquired.
11706                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11707            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11708            default:
11709                // If we're asleep then pause applications unconditionally.
11710                return true;
11711        }
11712    }
11713
11714    /** Pokes the task persister. */
11715    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11716        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11717    }
11718
11719    /** Notifies all listeners when the task stack has changed. */
11720    void notifyTaskStackChangedLocked() {
11721        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11722        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11723        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11724        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11725    }
11726
11727    /** Notifies all listeners when an Activity is pinned. */
11728    void notifyActivityPinnedLocked() {
11729        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11730        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11731    }
11732
11733    /**
11734     * Notifies all listeners when an attempt was made to start an an activity that is already
11735     * running in the pinned stack and the activity was not actually started, but the task is
11736     * either brought to the front or a new Intent is delivered to it.
11737     */
11738    void notifyPinnedActivityRestartAttemptLocked() {
11739        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11740        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11741    }
11742
11743    /** Notifies all listeners when the pinned stack animation ends. */
11744    @Override
11745    public void notifyPinnedStackAnimationEnded() {
11746        synchronized (this) {
11747            mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11748            mHandler.obtainMessage(
11749                    NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11750        }
11751    }
11752
11753    @Override
11754    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11755        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11756    }
11757
11758    @Override
11759    public boolean shutdown(int timeout) {
11760        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11761                != PackageManager.PERMISSION_GRANTED) {
11762            throw new SecurityException("Requires permission "
11763                    + android.Manifest.permission.SHUTDOWN);
11764        }
11765
11766        boolean timedout = false;
11767
11768        synchronized(this) {
11769            mShuttingDown = true;
11770            updateEventDispatchingLocked();
11771            timedout = mStackSupervisor.shutdownLocked(timeout);
11772        }
11773
11774        mAppOpsService.shutdown();
11775        if (mUsageStatsService != null) {
11776            mUsageStatsService.prepareShutdown();
11777        }
11778        mBatteryStatsService.shutdown();
11779        synchronized (this) {
11780            mProcessStats.shutdownLocked();
11781            notifyTaskPersisterLocked(null, true);
11782        }
11783
11784        return timedout;
11785    }
11786
11787    public final void activitySlept(IBinder token) {
11788        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11789
11790        final long origId = Binder.clearCallingIdentity();
11791
11792        synchronized (this) {
11793            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11794            if (r != null) {
11795                mStackSupervisor.activitySleptLocked(r);
11796            }
11797        }
11798
11799        Binder.restoreCallingIdentity(origId);
11800    }
11801
11802    private String lockScreenShownToString() {
11803        switch (mLockScreenShown) {
11804            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11805            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11806            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11807            default: return "Unknown=" + mLockScreenShown;
11808        }
11809    }
11810
11811    void logLockScreen(String msg) {
11812        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11813                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11814                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11815                + " mSleeping=" + mSleeping);
11816    }
11817
11818    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11819        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11820        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11821        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11822            boolean wasRunningVoice = mRunningVoice != null;
11823            mRunningVoice = session;
11824            if (!wasRunningVoice) {
11825                mVoiceWakeLock.acquire();
11826                updateSleepIfNeededLocked();
11827            }
11828        }
11829    }
11830
11831    private void updateEventDispatchingLocked() {
11832        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11833    }
11834
11835    public void setLockScreenShown(boolean showing, boolean occluded) {
11836        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11837                != PackageManager.PERMISSION_GRANTED) {
11838            throw new SecurityException("Requires permission "
11839                    + android.Manifest.permission.DEVICE_POWER);
11840        }
11841
11842        synchronized(this) {
11843            long ident = Binder.clearCallingIdentity();
11844            try {
11845                if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
11846                mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11847                if (showing && occluded) {
11848                    // The lock screen is currently showing, but is occluded by a window that can
11849                    // show on top of the lock screen. In this can we want to dismiss the docked
11850                    // stack since it will be complicated/risky to try to put the activity on top
11851                    // of the lock screen in the right fullscreen configuration.
11852                    mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
11853                            mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
11854                }
11855
11856                updateSleepIfNeededLocked();
11857            } finally {
11858                Binder.restoreCallingIdentity(ident);
11859            }
11860        }
11861    }
11862
11863    @Override
11864    public void notifyLockedProfile(@UserIdInt int userId) {
11865        try {
11866            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11867                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11868            }
11869        } catch (RemoteException ex) {
11870            throw new SecurityException("Fail to check is caller a privileged app", ex);
11871        }
11872
11873        synchronized (this) {
11874            if (mStackSupervisor.isUserLockedProfile(userId)) {
11875                final long ident = Binder.clearCallingIdentity();
11876                try {
11877                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11878
11879                    // Drop locked freeform tasks out into the fullscreen stack.
11880                    // TODO: Redact the tasks in place. It's much better to keep them on the screen
11881                    //       where they were before, but in an obscured state.
11882                    mStackSupervisor.moveProfileTasksFromFreeformToFullscreenStackLocked(userId);
11883
11884                    if (mUserController.isLockScreenDisabled(currentUserId)) {
11885                        // If there is no device lock, we will show the profile's credential page.
11886                        mActivityStarter.showConfirmDeviceCredential(userId);
11887                    } else {
11888                        // Showing launcher to avoid user entering credential twice.
11889                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11890                    }
11891                } finally {
11892                    Binder.restoreCallingIdentity(ident);
11893                }
11894            }
11895        }
11896    }
11897
11898    @Override
11899    public void startConfirmDeviceCredentialIntent(Intent intent) {
11900        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11901        synchronized (this) {
11902            final long ident = Binder.clearCallingIdentity();
11903            try {
11904                mActivityStarter.startConfirmCredentialIntent(intent);
11905            } finally {
11906                Binder.restoreCallingIdentity(ident);
11907            }
11908        }
11909    }
11910
11911    @Override
11912    public void stopAppSwitches() {
11913        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11914                != PackageManager.PERMISSION_GRANTED) {
11915            throw new SecurityException("viewquires permission "
11916                    + android.Manifest.permission.STOP_APP_SWITCHES);
11917        }
11918
11919        synchronized(this) {
11920            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11921                    + APP_SWITCH_DELAY_TIME;
11922            mDidAppSwitch = false;
11923            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11924            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11925            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11926        }
11927    }
11928
11929    public void resumeAppSwitches() {
11930        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11931                != PackageManager.PERMISSION_GRANTED) {
11932            throw new SecurityException("Requires permission "
11933                    + android.Manifest.permission.STOP_APP_SWITCHES);
11934        }
11935
11936        synchronized(this) {
11937            // Note that we don't execute any pending app switches... we will
11938            // let those wait until either the timeout, or the next start
11939            // activity request.
11940            mAppSwitchesAllowedTime = 0;
11941        }
11942    }
11943
11944    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11945            int callingPid, int callingUid, String name) {
11946        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11947            return true;
11948        }
11949
11950        int perm = checkComponentPermission(
11951                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11952                sourceUid, -1, true);
11953        if (perm == PackageManager.PERMISSION_GRANTED) {
11954            return true;
11955        }
11956
11957        // If the actual IPC caller is different from the logical source, then
11958        // also see if they are allowed to control app switches.
11959        if (callingUid != -1 && callingUid != sourceUid) {
11960            perm = checkComponentPermission(
11961                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11962                    callingUid, -1, true);
11963            if (perm == PackageManager.PERMISSION_GRANTED) {
11964                return true;
11965            }
11966        }
11967
11968        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11969        return false;
11970    }
11971
11972    public void setDebugApp(String packageName, boolean waitForDebugger,
11973            boolean persistent) {
11974        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11975                "setDebugApp()");
11976
11977        long ident = Binder.clearCallingIdentity();
11978        try {
11979            // Note that this is not really thread safe if there are multiple
11980            // callers into it at the same time, but that's not a situation we
11981            // care about.
11982            if (persistent) {
11983                final ContentResolver resolver = mContext.getContentResolver();
11984                Settings.Global.putString(
11985                    resolver, Settings.Global.DEBUG_APP,
11986                    packageName);
11987                Settings.Global.putInt(
11988                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11989                    waitForDebugger ? 1 : 0);
11990            }
11991
11992            synchronized (this) {
11993                if (!persistent) {
11994                    mOrigDebugApp = mDebugApp;
11995                    mOrigWaitForDebugger = mWaitForDebugger;
11996                }
11997                mDebugApp = packageName;
11998                mWaitForDebugger = waitForDebugger;
11999                mDebugTransient = !persistent;
12000                if (packageName != null) {
12001                    forceStopPackageLocked(packageName, -1, false, false, true, true,
12002                            false, UserHandle.USER_ALL, "set debug app");
12003                }
12004            }
12005        } finally {
12006            Binder.restoreCallingIdentity(ident);
12007        }
12008    }
12009
12010    void setTrackAllocationApp(ApplicationInfo app, String processName) {
12011        synchronized (this) {
12012            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12013            if (!isDebuggable) {
12014                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12015                    throw new SecurityException("Process not debuggable: " + app.packageName);
12016                }
12017            }
12018
12019            mTrackAllocationApp = processName;
12020        }
12021    }
12022
12023    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
12024        synchronized (this) {
12025            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12026            if (!isDebuggable) {
12027                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12028                    throw new SecurityException("Process not debuggable: " + app.packageName);
12029                }
12030            }
12031            mProfileApp = processName;
12032            mProfileFile = profilerInfo.profileFile;
12033            if (mProfileFd != null) {
12034                try {
12035                    mProfileFd.close();
12036                } catch (IOException e) {
12037                }
12038                mProfileFd = null;
12039            }
12040            mProfileFd = profilerInfo.profileFd;
12041            mSamplingInterval = profilerInfo.samplingInterval;
12042            mAutoStopProfiler = profilerInfo.autoStopProfiler;
12043            mProfileType = 0;
12044        }
12045    }
12046
12047    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
12048        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12049        if (!isDebuggable) {
12050            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12051                throw new SecurityException("Process not debuggable: " + app.packageName);
12052            }
12053        }
12054        mNativeDebuggingApp = processName;
12055    }
12056
12057    @Override
12058    public void setAlwaysFinish(boolean enabled) {
12059        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
12060                "setAlwaysFinish()");
12061
12062        long ident = Binder.clearCallingIdentity();
12063        try {
12064            Settings.Global.putInt(
12065                    mContext.getContentResolver(),
12066                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
12067
12068            synchronized (this) {
12069                mAlwaysFinishActivities = enabled;
12070            }
12071        } finally {
12072            Binder.restoreCallingIdentity(ident);
12073        }
12074    }
12075
12076    @Override
12077    public void setLenientBackgroundCheck(boolean enabled) {
12078        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
12079                "setLenientBackgroundCheck()");
12080
12081        long ident = Binder.clearCallingIdentity();
12082        try {
12083            Settings.Global.putInt(
12084                    mContext.getContentResolver(),
12085                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
12086
12087            synchronized (this) {
12088                mLenientBackgroundCheck = enabled;
12089            }
12090        } finally {
12091            Binder.restoreCallingIdentity(ident);
12092        }
12093    }
12094
12095    @Override
12096    public void setActivityController(IActivityController controller, boolean imAMonkey) {
12097        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12098                "setActivityController()");
12099        synchronized (this) {
12100            mController = controller;
12101            mControllerIsAMonkey = imAMonkey;
12102            Watchdog.getInstance().setActivityController(controller);
12103        }
12104    }
12105
12106    @Override
12107    public void setUserIsMonkey(boolean userIsMonkey) {
12108        synchronized (this) {
12109            synchronized (mPidsSelfLocked) {
12110                final int callingPid = Binder.getCallingPid();
12111                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
12112                if (precessRecord == null) {
12113                    throw new SecurityException("Unknown process: " + callingPid);
12114                }
12115                if (precessRecord.instrumentationUiAutomationConnection  == null) {
12116                    throw new SecurityException("Only an instrumentation process "
12117                            + "with a UiAutomation can call setUserIsMonkey");
12118                }
12119            }
12120            mUserIsMonkey = userIsMonkey;
12121        }
12122    }
12123
12124    @Override
12125    public boolean isUserAMonkey() {
12126        synchronized (this) {
12127            // If there is a controller also implies the user is a monkey.
12128            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12129        }
12130    }
12131
12132    public void requestBugReport(int bugreportType) {
12133        String service = null;
12134        switch (bugreportType) {
12135            case ActivityManager.BUGREPORT_OPTION_FULL:
12136                service = "bugreport";
12137                break;
12138            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12139                service = "bugreportplus";
12140                break;
12141            case ActivityManager.BUGREPORT_OPTION_REMOTE:
12142                service = "bugreportremote";
12143                break;
12144            case ActivityManager.BUGREPORT_OPTION_WEAR:
12145                service = "bugreportwear";
12146                break;
12147        }
12148        if (service == null) {
12149            throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12150                    + bugreportType);
12151        }
12152        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12153        SystemProperties.set("ctl.start", service);
12154    }
12155
12156    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12157        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12158    }
12159
12160    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12161        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
12162            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12163        }
12164        return KEY_DISPATCHING_TIMEOUT;
12165    }
12166
12167    @Override
12168    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12169        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12170                != PackageManager.PERMISSION_GRANTED) {
12171            throw new SecurityException("Requires permission "
12172                    + android.Manifest.permission.FILTER_EVENTS);
12173        }
12174        ProcessRecord proc;
12175        long timeout;
12176        synchronized (this) {
12177            synchronized (mPidsSelfLocked) {
12178                proc = mPidsSelfLocked.get(pid);
12179            }
12180            timeout = getInputDispatchingTimeoutLocked(proc);
12181        }
12182
12183        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12184            return -1;
12185        }
12186
12187        return timeout;
12188    }
12189
12190    /**
12191     * Handle input dispatching timeouts.
12192     * Returns whether input dispatching should be aborted or not.
12193     */
12194    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12195            final ActivityRecord activity, final ActivityRecord parent,
12196            final boolean aboveSystem, String reason) {
12197        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12198                != PackageManager.PERMISSION_GRANTED) {
12199            throw new SecurityException("Requires permission "
12200                    + android.Manifest.permission.FILTER_EVENTS);
12201        }
12202
12203        final String annotation;
12204        if (reason == null) {
12205            annotation = "Input dispatching timed out";
12206        } else {
12207            annotation = "Input dispatching timed out (" + reason + ")";
12208        }
12209
12210        if (proc != null) {
12211            synchronized (this) {
12212                if (proc.debugging) {
12213                    return false;
12214                }
12215
12216                if (mDidDexOpt) {
12217                    // Give more time since we were dexopting.
12218                    mDidDexOpt = false;
12219                    return false;
12220                }
12221
12222                if (proc.instrumentationClass != null) {
12223                    Bundle info = new Bundle();
12224                    info.putString("shortMsg", "keyDispatchingTimedOut");
12225                    info.putString("longMsg", annotation);
12226                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12227                    return true;
12228                }
12229            }
12230            mHandler.post(new Runnable() {
12231                @Override
12232                public void run() {
12233                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12234                }
12235            });
12236        }
12237
12238        return true;
12239    }
12240
12241    @Override
12242    public Bundle getAssistContextExtras(int requestType) {
12243        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12244                null, null, true /* focused */, true /* newSessionId */,
12245                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
12246        if (pae == null) {
12247            return null;
12248        }
12249        synchronized (pae) {
12250            while (!pae.haveResult) {
12251                try {
12252                    pae.wait();
12253                } catch (InterruptedException e) {
12254                }
12255            }
12256        }
12257        synchronized (this) {
12258            buildAssistBundleLocked(pae, pae.result);
12259            mPendingAssistExtras.remove(pae);
12260            mUiHandler.removeCallbacks(pae);
12261        }
12262        return pae.extras;
12263    }
12264
12265    @Override
12266    public boolean isAssistDataAllowedOnCurrentActivity() {
12267        int userId;
12268        synchronized (this) {
12269            userId = mUserController.getCurrentUserIdLocked();
12270            ActivityRecord activity = getFocusedStack().topActivity();
12271            if (activity == null) {
12272                return false;
12273            }
12274            userId = activity.userId;
12275        }
12276        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12277                Context.DEVICE_POLICY_SERVICE);
12278        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12279    }
12280
12281    @Override
12282    public boolean showAssistFromActivity(IBinder token, Bundle args) {
12283        long ident = Binder.clearCallingIdentity();
12284        try {
12285            synchronized (this) {
12286                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12287                ActivityRecord top = getFocusedStack().topActivity();
12288                if (top != caller) {
12289                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12290                            + " is not current top " + top);
12291                    return false;
12292                }
12293                if (!top.nowVisible) {
12294                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12295                            + " is not visible");
12296                    return false;
12297                }
12298            }
12299            AssistUtils utils = new AssistUtils(mContext);
12300            return utils.showSessionForActiveService(args,
12301                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
12302        } finally {
12303            Binder.restoreCallingIdentity(ident);
12304        }
12305    }
12306
12307    @Override
12308    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12309            Bundle receiverExtras,
12310            IBinder activityToken, boolean focused, boolean newSessionId) {
12311        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12312                activityToken, focused, newSessionId,
12313                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
12314                != null;
12315    }
12316
12317    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12318            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12319            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12320        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12321                "enqueueAssistContext()");
12322        synchronized (this) {
12323            ActivityRecord activity = getFocusedStack().topActivity();
12324            if (activity == null) {
12325                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12326                return null;
12327            }
12328            if (activity.app == null || activity.app.thread == null) {
12329                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12330                return null;
12331            }
12332            if (focused) {
12333                if (activityToken != null) {
12334                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12335                    if (activity != caller) {
12336                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12337                                + " is not current top " + activity);
12338                        return null;
12339                    }
12340                }
12341            } else {
12342                activity = ActivityRecord.forTokenLocked(activityToken);
12343                if (activity == null) {
12344                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12345                            + " couldn't be found");
12346                    return null;
12347                }
12348            }
12349
12350            PendingAssistExtras pae;
12351            Bundle extras = new Bundle();
12352            if (args != null) {
12353                extras.putAll(args);
12354            }
12355            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12356            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12357            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12358                    userHandle);
12359            // Increment the sessionId if necessary
12360            if (newSessionId) {
12361                mViSessionId++;
12362            }
12363            try {
12364                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12365                        requestType, mViSessionId);
12366                mPendingAssistExtras.add(pae);
12367                mUiHandler.postDelayed(pae, timeout);
12368            } catch (RemoteException e) {
12369                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12370                return null;
12371            }
12372            return pae;
12373        }
12374    }
12375
12376    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12377        IResultReceiver receiver;
12378        synchronized (this) {
12379            mPendingAssistExtras.remove(pae);
12380            receiver = pae.receiver;
12381        }
12382        if (receiver != null) {
12383            // Caller wants result sent back to them.
12384            Bundle sendBundle = new Bundle();
12385            // At least return the receiver extras
12386            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12387                    pae.receiverExtras);
12388            try {
12389                pae.receiver.send(0, sendBundle);
12390            } catch (RemoteException e) {
12391            }
12392        }
12393    }
12394
12395    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12396        if (result != null) {
12397            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12398        }
12399        if (pae.hint != null) {
12400            pae.extras.putBoolean(pae.hint, true);
12401        }
12402    }
12403
12404    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12405            AssistContent content, Uri referrer) {
12406        PendingAssistExtras pae = (PendingAssistExtras)token;
12407        synchronized (pae) {
12408            pae.result = extras;
12409            pae.structure = structure;
12410            pae.content = content;
12411            if (referrer != null) {
12412                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12413            }
12414            pae.haveResult = true;
12415            pae.notifyAll();
12416            if (pae.intent == null && pae.receiver == null) {
12417                // Caller is just waiting for the result.
12418                return;
12419            }
12420        }
12421
12422        // We are now ready to launch the assist activity.
12423        IResultReceiver sendReceiver = null;
12424        Bundle sendBundle = null;
12425        synchronized (this) {
12426            buildAssistBundleLocked(pae, extras);
12427            boolean exists = mPendingAssistExtras.remove(pae);
12428            mUiHandler.removeCallbacks(pae);
12429            if (!exists) {
12430                // Timed out.
12431                return;
12432            }
12433            if ((sendReceiver=pae.receiver) != null) {
12434                // Caller wants result sent back to them.
12435                sendBundle = new Bundle();
12436                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12437                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12438                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12439                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12440                        pae.receiverExtras);
12441            }
12442        }
12443        if (sendReceiver != null) {
12444            try {
12445                sendReceiver.send(0, sendBundle);
12446            } catch (RemoteException e) {
12447            }
12448            return;
12449        }
12450
12451        long ident = Binder.clearCallingIdentity();
12452        try {
12453            pae.intent.replaceExtras(pae.extras);
12454            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12455                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12456                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12457            closeSystemDialogs("assist");
12458            try {
12459                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12460            } catch (ActivityNotFoundException e) {
12461                Slog.w(TAG, "No activity to handle assist action.", e);
12462            }
12463        } finally {
12464            Binder.restoreCallingIdentity(ident);
12465        }
12466    }
12467
12468    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12469            Bundle args) {
12470        return enqueueAssistContext(requestType, intent, hint, null, null, null,
12471                true /* focused */, true /* newSessionId */,
12472                userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12473    }
12474
12475    public void registerProcessObserver(IProcessObserver observer) {
12476        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12477                "registerProcessObserver()");
12478        synchronized (this) {
12479            mProcessObservers.register(observer);
12480        }
12481    }
12482
12483    @Override
12484    public void unregisterProcessObserver(IProcessObserver observer) {
12485        synchronized (this) {
12486            mProcessObservers.unregister(observer);
12487        }
12488    }
12489
12490    @Override
12491    public void registerUidObserver(IUidObserver observer, int which) {
12492        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12493                "registerUidObserver()");
12494        synchronized (this) {
12495            mUidObservers.register(observer, which);
12496        }
12497    }
12498
12499    @Override
12500    public void unregisterUidObserver(IUidObserver observer) {
12501        synchronized (this) {
12502            mUidObservers.unregister(observer);
12503        }
12504    }
12505
12506    @Override
12507    public boolean convertFromTranslucent(IBinder token) {
12508        final long origId = Binder.clearCallingIdentity();
12509        try {
12510            synchronized (this) {
12511                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12512                if (r == null) {
12513                    return false;
12514                }
12515                final boolean translucentChanged = r.changeWindowTranslucency(true);
12516                if (translucentChanged) {
12517                    r.task.stack.releaseBackgroundResources(r);
12518                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12519                }
12520                mWindowManager.setAppFullscreen(token, true);
12521                return translucentChanged;
12522            }
12523        } finally {
12524            Binder.restoreCallingIdentity(origId);
12525        }
12526    }
12527
12528    @Override
12529    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12530        final long origId = Binder.clearCallingIdentity();
12531        try {
12532            synchronized (this) {
12533                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12534                if (r == null) {
12535                    return false;
12536                }
12537                int index = r.task.mActivities.lastIndexOf(r);
12538                if (index > 0) {
12539                    ActivityRecord under = r.task.mActivities.get(index - 1);
12540                    under.returningOptions = options;
12541                }
12542                final boolean translucentChanged = r.changeWindowTranslucency(false);
12543                if (translucentChanged) {
12544                    r.task.stack.convertActivityToTranslucent(r);
12545                }
12546                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12547                mWindowManager.setAppFullscreen(token, false);
12548                return translucentChanged;
12549            }
12550        } finally {
12551            Binder.restoreCallingIdentity(origId);
12552        }
12553    }
12554
12555    @Override
12556    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12557        final long origId = Binder.clearCallingIdentity();
12558        try {
12559            synchronized (this) {
12560                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12561                if (r != null) {
12562                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12563                }
12564            }
12565            return false;
12566        } finally {
12567            Binder.restoreCallingIdentity(origId);
12568        }
12569    }
12570
12571    @Override
12572    public boolean isBackgroundVisibleBehind(IBinder token) {
12573        final long origId = Binder.clearCallingIdentity();
12574        try {
12575            synchronized (this) {
12576                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12577                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12578                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12579                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12580                return visible;
12581            }
12582        } finally {
12583            Binder.restoreCallingIdentity(origId);
12584        }
12585    }
12586
12587    @Override
12588    public ActivityOptions getActivityOptions(IBinder token) {
12589        final long origId = Binder.clearCallingIdentity();
12590        try {
12591            synchronized (this) {
12592                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12593                if (r != null) {
12594                    final ActivityOptions activityOptions = r.pendingOptions;
12595                    r.pendingOptions = null;
12596                    return activityOptions;
12597                }
12598                return null;
12599            }
12600        } finally {
12601            Binder.restoreCallingIdentity(origId);
12602        }
12603    }
12604
12605    @Override
12606    public void setImmersive(IBinder token, boolean immersive) {
12607        synchronized(this) {
12608            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12609            if (r == null) {
12610                throw new IllegalArgumentException();
12611            }
12612            r.immersive = immersive;
12613
12614            // update associated state if we're frontmost
12615            if (r == mFocusedActivity) {
12616                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12617                applyUpdateLockStateLocked(r);
12618            }
12619        }
12620    }
12621
12622    @Override
12623    public boolean isImmersive(IBinder token) {
12624        synchronized (this) {
12625            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12626            if (r == null) {
12627                throw new IllegalArgumentException();
12628            }
12629            return r.immersive;
12630        }
12631    }
12632
12633    public void setVrThread(int tid) {
12634        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12635            throw new UnsupportedOperationException("VR mode not supported on this device!");
12636        }
12637
12638        synchronized (this) {
12639            ProcessRecord proc;
12640            synchronized (mPidsSelfLocked) {
12641                final int pid = Binder.getCallingPid();
12642                proc = mPidsSelfLocked.get(pid);
12643
12644                if (proc != null && mInVrMode && tid >= 0) {
12645                    // ensure the tid belongs to the process
12646                    if (!Process.isThreadInProcess(pid, tid)) {
12647                        throw new IllegalArgumentException("VR thread does not belong to process");
12648                    }
12649
12650                    // reset existing VR thread to CFS if this thread still exists and belongs to
12651                    // the calling process
12652                    if (proc.vrThreadTid != 0
12653                            && Process.isThreadInProcess(pid, proc.vrThreadTid)) {
12654                        try {
12655                            Process.setThreadScheduler(proc.vrThreadTid, Process.SCHED_OTHER, 0);
12656                        } catch (IllegalArgumentException e) {
12657                            // Ignore this.  Only occurs in race condition where previous VR thread
12658                            // was destroyed during this method call.
12659                        }
12660                    }
12661
12662                    proc.vrThreadTid = tid;
12663
12664                    // promote to FIFO now if the tid is non-zero
12665                    try {
12666                        if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
12667                            proc.vrThreadTid > 0) {
12668                            Process.setThreadScheduler(proc.vrThreadTid,
12669                                Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12670                        }
12671                    } catch (IllegalArgumentException e) {
12672                        Slog.e(TAG, "Failed to set scheduling policy, thread does"
12673                               + " not exist:\n" + e);
12674                    }
12675                }
12676            }
12677        }
12678    }
12679
12680    @Override
12681    public void setRenderThread(int tid) {
12682        synchronized (this) {
12683            ProcessRecord proc;
12684            synchronized (mPidsSelfLocked) {
12685                int pid = Binder.getCallingPid();
12686                proc = mPidsSelfLocked.get(pid);
12687                if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
12688                    // ensure the tid belongs to the process
12689                    if (!Process.isThreadInProcess(pid, tid)) {
12690                        throw new IllegalArgumentException(
12691                            "Render thread does not belong to process");
12692                    }
12693                    proc.renderThreadTid = tid;
12694                    if (DEBUG_OOM_ADJ) {
12695                        Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
12696                    }
12697                    // promote to FIFO now
12698                    if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
12699                        if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
12700                        if (mUseFifoUiScheduling) {
12701                            Process.setThreadScheduler(proc.renderThreadTid,
12702                                Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12703                        } else {
12704                            Process.setThreadPriority(proc.renderThreadTid, -10);
12705                        }
12706                    }
12707                } else {
12708                    if (DEBUG_OOM_ADJ) {
12709                        Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
12710                               "PID: " + pid + ", TID: " + tid + " FIFO: " +
12711                               mUseFifoUiScheduling);
12712                    }
12713                }
12714            }
12715        }
12716    }
12717
12718    @Override
12719    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12720        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12721            throw new UnsupportedOperationException("VR mode not supported on this device!");
12722        }
12723
12724        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12725
12726        ActivityRecord r;
12727        synchronized (this) {
12728            r = ActivityRecord.isInStackLocked(token);
12729        }
12730
12731        if (r == null) {
12732            throw new IllegalArgumentException();
12733        }
12734
12735        int err;
12736        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12737                VrManagerInternal.NO_ERROR) {
12738            return err;
12739        }
12740
12741        synchronized(this) {
12742            r.requestedVrComponent = (enabled) ? packageName : null;
12743
12744            // Update associated state if this activity is currently focused
12745            if (r == mFocusedActivity) {
12746                applyUpdateVrModeLocked(r);
12747            }
12748            return 0;
12749        }
12750    }
12751
12752    @Override
12753    public boolean isVrModePackageEnabled(ComponentName packageName) {
12754        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12755            throw new UnsupportedOperationException("VR mode not supported on this device!");
12756        }
12757
12758        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12759
12760        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12761                VrManagerInternal.NO_ERROR;
12762    }
12763
12764    public boolean isTopActivityImmersive() {
12765        enforceNotIsolatedCaller("startActivity");
12766        synchronized (this) {
12767            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12768            return (r != null) ? r.immersive : false;
12769        }
12770    }
12771
12772    @Override
12773    public boolean isTopOfTask(IBinder token) {
12774        synchronized (this) {
12775            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12776            if (r == null) {
12777                throw new IllegalArgumentException();
12778            }
12779            return r.task.getTopActivity() == r;
12780        }
12781    }
12782
12783    @Override
12784    public void setHasTopUi(boolean hasTopUi) throws RemoteException {
12785        if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
12786            String msg = "Permission Denial: setHasTopUi() from pid="
12787                    + Binder.getCallingPid()
12788                    + ", uid=" + Binder.getCallingUid()
12789                    + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
12790            Slog.w(TAG, msg);
12791            throw new SecurityException(msg);
12792        }
12793        final int pid = Binder.getCallingPid();
12794        final long origId = Binder.clearCallingIdentity();
12795        try {
12796            synchronized (this) {
12797                boolean changed = false;
12798                ProcessRecord pr;
12799                synchronized (mPidsSelfLocked) {
12800                    pr = mPidsSelfLocked.get(pid);
12801                    if (pr == null) {
12802                        Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
12803                        return;
12804                    }
12805                    if (pr.hasTopUi != hasTopUi) {
12806                        Slog.i(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
12807                        pr.hasTopUi = hasTopUi;
12808                        changed = true;
12809                    }
12810                }
12811                if (changed) {
12812                    updateOomAdjLocked(pr);
12813                }
12814            }
12815        } finally {
12816            Binder.restoreCallingIdentity(origId);
12817        }
12818    }
12819
12820    public final void enterSafeMode() {
12821        synchronized(this) {
12822            // It only makes sense to do this before the system is ready
12823            // and started launching other packages.
12824            if (!mSystemReady) {
12825                try {
12826                    AppGlobals.getPackageManager().enterSafeMode();
12827                } catch (RemoteException e) {
12828                }
12829            }
12830
12831            mSafeMode = true;
12832        }
12833    }
12834
12835    public final void showSafeModeOverlay() {
12836        View v = LayoutInflater.from(mContext).inflate(
12837                com.android.internal.R.layout.safe_mode, null);
12838        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12839        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12840        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12841        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12842        lp.gravity = Gravity.BOTTOM | Gravity.START;
12843        lp.format = v.getBackground().getOpacity();
12844        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12845                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12846        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12847        ((WindowManager)mContext.getSystemService(
12848                Context.WINDOW_SERVICE)).addView(v, lp);
12849    }
12850
12851    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12852        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12853            return;
12854        }
12855        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12856        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12857        synchronized (stats) {
12858            if (mBatteryStatsService.isOnBattery()) {
12859                mBatteryStatsService.enforceCallingPermission();
12860                int MY_UID = Binder.getCallingUid();
12861                final int uid;
12862                if (sender == null) {
12863                    uid = sourceUid;
12864                } else {
12865                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12866                }
12867                BatteryStatsImpl.Uid.Pkg pkg =
12868                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12869                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12870                pkg.noteWakeupAlarmLocked(tag);
12871            }
12872        }
12873    }
12874
12875    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12876        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12877            return;
12878        }
12879        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12880        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12881        synchronized (stats) {
12882            mBatteryStatsService.enforceCallingPermission();
12883            int MY_UID = Binder.getCallingUid();
12884            final int uid;
12885            if (sender == null) {
12886                uid = sourceUid;
12887            } else {
12888                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12889            }
12890            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12891        }
12892    }
12893
12894    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12895        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12896            return;
12897        }
12898        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12899        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12900        synchronized (stats) {
12901            mBatteryStatsService.enforceCallingPermission();
12902            int MY_UID = Binder.getCallingUid();
12903            final int uid;
12904            if (sender == null) {
12905                uid = sourceUid;
12906            } else {
12907                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12908            }
12909            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12910        }
12911    }
12912
12913    public boolean killPids(int[] pids, String pReason, boolean secure) {
12914        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12915            throw new SecurityException("killPids only available to the system");
12916        }
12917        String reason = (pReason == null) ? "Unknown" : pReason;
12918        // XXX Note: don't acquire main activity lock here, because the window
12919        // manager calls in with its locks held.
12920
12921        boolean killed = false;
12922        synchronized (mPidsSelfLocked) {
12923            int worstType = 0;
12924            for (int i=0; i<pids.length; i++) {
12925                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12926                if (proc != null) {
12927                    int type = proc.setAdj;
12928                    if (type > worstType) {
12929                        worstType = type;
12930                    }
12931                }
12932            }
12933
12934            // If the worst oom_adj is somewhere in the cached proc LRU range,
12935            // then constrain it so we will kill all cached procs.
12936            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12937                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12938                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12939            }
12940
12941            // If this is not a secure call, don't let it kill processes that
12942            // are important.
12943            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12944                worstType = ProcessList.SERVICE_ADJ;
12945            }
12946
12947            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12948            for (int i=0; i<pids.length; i++) {
12949                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12950                if (proc == null) {
12951                    continue;
12952                }
12953                int adj = proc.setAdj;
12954                if (adj >= worstType && !proc.killedByAm) {
12955                    proc.kill(reason, true);
12956                    killed = true;
12957                }
12958            }
12959        }
12960        return killed;
12961    }
12962
12963    @Override
12964    public void killUid(int appId, int userId, String reason) {
12965        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12966        synchronized (this) {
12967            final long identity = Binder.clearCallingIdentity();
12968            try {
12969                killPackageProcessesLocked(null, appId, userId,
12970                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12971                        reason != null ? reason : "kill uid");
12972            } finally {
12973                Binder.restoreCallingIdentity(identity);
12974            }
12975        }
12976    }
12977
12978    @Override
12979    public boolean killProcessesBelowForeground(String reason) {
12980        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12981            throw new SecurityException("killProcessesBelowForeground() only available to system");
12982        }
12983
12984        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12985    }
12986
12987    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12988        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12989            throw new SecurityException("killProcessesBelowAdj() only available to system");
12990        }
12991
12992        boolean killed = false;
12993        synchronized (mPidsSelfLocked) {
12994            final int size = mPidsSelfLocked.size();
12995            for (int i = 0; i < size; i++) {
12996                final int pid = mPidsSelfLocked.keyAt(i);
12997                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12998                if (proc == null) continue;
12999
13000                final int adj = proc.setAdj;
13001                if (adj > belowAdj && !proc.killedByAm) {
13002                    proc.kill(reason, true);
13003                    killed = true;
13004                }
13005            }
13006        }
13007        return killed;
13008    }
13009
13010    @Override
13011    public void hang(final IBinder who, boolean allowRestart) {
13012        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13013                != PackageManager.PERMISSION_GRANTED) {
13014            throw new SecurityException("Requires permission "
13015                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13016        }
13017
13018        final IBinder.DeathRecipient death = new DeathRecipient() {
13019            @Override
13020            public void binderDied() {
13021                synchronized (this) {
13022                    notifyAll();
13023                }
13024            }
13025        };
13026
13027        try {
13028            who.linkToDeath(death, 0);
13029        } catch (RemoteException e) {
13030            Slog.w(TAG, "hang: given caller IBinder is already dead.");
13031            return;
13032        }
13033
13034        synchronized (this) {
13035            Watchdog.getInstance().setAllowRestart(allowRestart);
13036            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
13037            synchronized (death) {
13038                while (who.isBinderAlive()) {
13039                    try {
13040                        death.wait();
13041                    } catch (InterruptedException e) {
13042                    }
13043                }
13044            }
13045            Watchdog.getInstance().setAllowRestart(true);
13046        }
13047    }
13048
13049    @Override
13050    public void restart() {
13051        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13052                != PackageManager.PERMISSION_GRANTED) {
13053            throw new SecurityException("Requires permission "
13054                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13055        }
13056
13057        Log.i(TAG, "Sending shutdown broadcast...");
13058
13059        BroadcastReceiver br = new BroadcastReceiver() {
13060            @Override public void onReceive(Context context, Intent intent) {
13061                // Now the broadcast is done, finish up the low-level shutdown.
13062                Log.i(TAG, "Shutting down activity manager...");
13063                shutdown(10000);
13064                Log.i(TAG, "Shutdown complete, restarting!");
13065                Process.killProcess(Process.myPid());
13066                System.exit(10);
13067            }
13068        };
13069
13070        // First send the high-level shut down broadcast.
13071        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
13072        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
13073        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
13074        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
13075        mContext.sendOrderedBroadcastAsUser(intent,
13076                UserHandle.ALL, null, br, mHandler, 0, null, null);
13077        */
13078        br.onReceive(mContext, intent);
13079    }
13080
13081    private long getLowRamTimeSinceIdle(long now) {
13082        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
13083    }
13084
13085    @Override
13086    public void performIdleMaintenance() {
13087        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13088                != PackageManager.PERMISSION_GRANTED) {
13089            throw new SecurityException("Requires permission "
13090                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13091        }
13092
13093        synchronized (this) {
13094            final long now = SystemClock.uptimeMillis();
13095            final long timeSinceLastIdle = now - mLastIdleTime;
13096            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
13097            mLastIdleTime = now;
13098            mLowRamTimeSinceLastIdle = 0;
13099            if (mLowRamStartTime != 0) {
13100                mLowRamStartTime = now;
13101            }
13102
13103            StringBuilder sb = new StringBuilder(128);
13104            sb.append("Idle maintenance over ");
13105            TimeUtils.formatDuration(timeSinceLastIdle, sb);
13106            sb.append(" low RAM for ");
13107            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13108            Slog.i(TAG, sb.toString());
13109
13110            // If at least 1/3 of our time since the last idle period has been spent
13111            // with RAM low, then we want to kill processes.
13112            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
13113
13114            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13115                ProcessRecord proc = mLruProcesses.get(i);
13116                if (proc.notCachedSinceIdle) {
13117                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
13118                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
13119                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
13120                        if (doKilling && proc.initialIdlePss != 0
13121                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
13122                            sb = new StringBuilder(128);
13123                            sb.append("Kill");
13124                            sb.append(proc.processName);
13125                            sb.append(" in idle maint: pss=");
13126                            sb.append(proc.lastPss);
13127                            sb.append(", swapPss=");
13128                            sb.append(proc.lastSwapPss);
13129                            sb.append(", initialPss=");
13130                            sb.append(proc.initialIdlePss);
13131                            sb.append(", period=");
13132                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
13133                            sb.append(", lowRamPeriod=");
13134                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13135                            Slog.wtfQuiet(TAG, sb.toString());
13136                            proc.kill("idle maint (pss " + proc.lastPss
13137                                    + " from " + proc.initialIdlePss + ")", true);
13138                        }
13139                    }
13140                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
13141                        && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
13142                    proc.notCachedSinceIdle = true;
13143                    proc.initialIdlePss = 0;
13144                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
13145                            mTestPssMode, isSleepingLocked(), now);
13146                }
13147            }
13148
13149            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
13150            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
13151        }
13152    }
13153
13154    @Override
13155    public void sendIdleJobTrigger() {
13156        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13157                != PackageManager.PERMISSION_GRANTED) {
13158            throw new SecurityException("Requires permission "
13159                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13160        }
13161
13162        final long ident = Binder.clearCallingIdentity();
13163        try {
13164            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
13165                    .setPackage("android")
13166                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13167            broadcastIntent(null, intent, null, null, 0, null, null, null,
13168                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
13169        } finally {
13170            Binder.restoreCallingIdentity(ident);
13171        }
13172    }
13173
13174    private void retrieveSettings() {
13175        final ContentResolver resolver = mContext.getContentResolver();
13176        final boolean freeformWindowManagement =
13177                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
13178                        || Settings.Global.getInt(
13179                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
13180        final boolean supportsPictureInPicture =
13181                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
13182
13183        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
13184        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
13185        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
13186        final boolean alwaysFinishActivities =
13187                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
13188        final boolean lenientBackgroundCheck =
13189                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
13190        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
13191        final boolean forceResizable = Settings.Global.getInt(
13192                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
13193        final boolean supportsLeanbackOnly =
13194                mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
13195
13196        // Transfer any global setting for forcing RTL layout, into a System Property
13197        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
13198
13199        final Configuration configuration = new Configuration();
13200        Settings.System.getConfiguration(resolver, configuration);
13201        if (forceRtl) {
13202            // This will take care of setting the correct layout direction flags
13203            configuration.setLayoutDirection(configuration.locale);
13204        }
13205
13206        synchronized (this) {
13207            mDebugApp = mOrigDebugApp = debugApp;
13208            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
13209            mAlwaysFinishActivities = alwaysFinishActivities;
13210            mLenientBackgroundCheck = lenientBackgroundCheck;
13211            mSupportsLeanbackOnly = supportsLeanbackOnly;
13212            mForceResizableActivities = forceResizable;
13213            mWindowManager.setForceResizableTasks(mForceResizableActivities);
13214            if (supportsMultiWindow || forceResizable) {
13215                mSupportsMultiWindow = true;
13216                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
13217                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
13218            } else {
13219                mSupportsMultiWindow = false;
13220                mSupportsFreeformWindowManagement = false;
13221                mSupportsPictureInPicture = false;
13222            }
13223            // This happens before any activities are started, so we can
13224            // change mConfiguration in-place.
13225            updateConfigurationLocked(configuration, null, true);
13226            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
13227                    "Initial config: " + mConfiguration);
13228
13229            // Load resources only after the current configuration has been set.
13230            final Resources res = mContext.getResources();
13231            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
13232            mThumbnailWidth = res.getDimensionPixelSize(
13233                    com.android.internal.R.dimen.thumbnail_width);
13234            mThumbnailHeight = res.getDimensionPixelSize(
13235                    com.android.internal.R.dimen.thumbnail_height);
13236            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
13237                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
13238            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
13239                    com.android.internal.R.string.config_appsNotReportingCrashes));
13240            if ((mConfiguration.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
13241                mFullscreenThumbnailScale = (float) res
13242                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
13243                    (float) mConfiguration.screenWidthDp;
13244            } else {
13245                mFullscreenThumbnailScale = res.getFraction(
13246                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
13247            }
13248        }
13249    }
13250
13251    public boolean testIsSystemReady() {
13252        // no need to synchronize(this) just to read & return the value
13253        return mSystemReady;
13254    }
13255
13256    public void systemReady(final Runnable goingCallback) {
13257        synchronized(this) {
13258            if (mSystemReady) {
13259                // If we're done calling all the receivers, run the next "boot phase" passed in
13260                // by the SystemServer
13261                if (goingCallback != null) {
13262                    goingCallback.run();
13263                }
13264                return;
13265            }
13266
13267            mLocalDeviceIdleController
13268                    = LocalServices.getService(DeviceIdleController.LocalService.class);
13269
13270            // Make sure we have the current profile info, since it is needed for security checks.
13271            mUserController.onSystemReady();
13272            mRecentTasks.onSystemReadyLocked();
13273            mAppOpsService.systemReady();
13274            mSystemReady = true;
13275        }
13276
13277        ArrayList<ProcessRecord> procsToKill = null;
13278        synchronized(mPidsSelfLocked) {
13279            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
13280                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13281                if (!isAllowedWhileBooting(proc.info)){
13282                    if (procsToKill == null) {
13283                        procsToKill = new ArrayList<ProcessRecord>();
13284                    }
13285                    procsToKill.add(proc);
13286                }
13287            }
13288        }
13289
13290        synchronized(this) {
13291            if (procsToKill != null) {
13292                for (int i=procsToKill.size()-1; i>=0; i--) {
13293                    ProcessRecord proc = procsToKill.get(i);
13294                    Slog.i(TAG, "Removing system update proc: " + proc);
13295                    removeProcessLocked(proc, true, false, "system update done");
13296                }
13297            }
13298
13299            // Now that we have cleaned up any update processes, we
13300            // are ready to start launching real processes and know that
13301            // we won't trample on them any more.
13302            mProcessesReady = true;
13303        }
13304
13305        Slog.i(TAG, "System now ready");
13306        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
13307            SystemClock.uptimeMillis());
13308
13309        synchronized(this) {
13310            // Make sure we have no pre-ready processes sitting around.
13311
13312            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
13313                ResolveInfo ri = mContext.getPackageManager()
13314                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
13315                                STOCK_PM_FLAGS);
13316                CharSequence errorMsg = null;
13317                if (ri != null) {
13318                    ActivityInfo ai = ri.activityInfo;
13319                    ApplicationInfo app = ai.applicationInfo;
13320                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
13321                        mTopAction = Intent.ACTION_FACTORY_TEST;
13322                        mTopData = null;
13323                        mTopComponent = new ComponentName(app.packageName,
13324                                ai.name);
13325                    } else {
13326                        errorMsg = mContext.getResources().getText(
13327                                com.android.internal.R.string.factorytest_not_system);
13328                    }
13329                } else {
13330                    errorMsg = mContext.getResources().getText(
13331                            com.android.internal.R.string.factorytest_no_action);
13332                }
13333                if (errorMsg != null) {
13334                    mTopAction = null;
13335                    mTopData = null;
13336                    mTopComponent = null;
13337                    Message msg = Message.obtain();
13338                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
13339                    msg.getData().putCharSequence("msg", errorMsg);
13340                    mUiHandler.sendMessage(msg);
13341                }
13342            }
13343        }
13344
13345        retrieveSettings();
13346        final int currentUserId;
13347        synchronized (this) {
13348            currentUserId = mUserController.getCurrentUserIdLocked();
13349            readGrantedUriPermissionsLocked();
13350        }
13351
13352        if (goingCallback != null) goingCallback.run();
13353
13354        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
13355                Integer.toString(currentUserId), currentUserId);
13356        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
13357                Integer.toString(currentUserId), currentUserId);
13358        mSystemServiceManager.startUser(currentUserId);
13359
13360        synchronized (this) {
13361            // Only start up encryption-aware persistent apps; once user is
13362            // unlocked we'll come back around and start unaware apps
13363            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
13364
13365            // Start up initial activity.
13366            mBooting = true;
13367            // Enable home activity for system user, so that the system can always boot
13368            if (UserManager.isSplitSystemUser()) {
13369                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
13370                try {
13371                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
13372                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
13373                            UserHandle.USER_SYSTEM);
13374                } catch (RemoteException e) {
13375                    throw e.rethrowAsRuntimeException();
13376                }
13377            }
13378            startHomeActivityLocked(currentUserId, "systemReady");
13379
13380            try {
13381                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
13382                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
13383                            + " data partition or your device will be unstable.");
13384                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
13385                }
13386            } catch (RemoteException e) {
13387            }
13388
13389            if (!Build.isBuildConsistent()) {
13390                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
13391                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
13392            }
13393
13394            long ident = Binder.clearCallingIdentity();
13395            try {
13396                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
13397                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13398                        | Intent.FLAG_RECEIVER_FOREGROUND);
13399                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13400                broadcastIntentLocked(null, null, intent,
13401                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
13402                        null, false, false, MY_PID, Process.SYSTEM_UID,
13403                        currentUserId);
13404                intent = new Intent(Intent.ACTION_USER_STARTING);
13405                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13406                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13407                broadcastIntentLocked(null, null, intent,
13408                        null, new IIntentReceiver.Stub() {
13409                            @Override
13410                            public void performReceive(Intent intent, int resultCode, String data,
13411                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13412                                    throws RemoteException {
13413                            }
13414                        }, 0, null, null,
13415                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13416                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13417            } catch (Throwable t) {
13418                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13419            } finally {
13420                Binder.restoreCallingIdentity(ident);
13421            }
13422            mStackSupervisor.resumeFocusedStackTopActivityLocked();
13423            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13424        }
13425    }
13426
13427    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13428        synchronized (this) {
13429            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13430        }
13431    }
13432
13433    void skipCurrentReceiverLocked(ProcessRecord app) {
13434        for (BroadcastQueue queue : mBroadcastQueues) {
13435            queue.skipCurrentReceiverLocked(app);
13436        }
13437    }
13438
13439    /**
13440     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13441     * The application process will exit immediately after this call returns.
13442     * @param app object of the crashing app, null for the system server
13443     * @param crashInfo describing the exception
13444     */
13445    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
13446        ProcessRecord r = findAppProcess(app, "Crash");
13447        final String processName = app == null ? "system_server"
13448                : (r == null ? "unknown" : r.processName);
13449
13450        handleApplicationCrashInner("crash", r, processName, crashInfo);
13451    }
13452
13453    /* Native crash reporting uses this inner version because it needs to be somewhat
13454     * decoupled from the AM-managed cleanup lifecycle
13455     */
13456    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13457            ApplicationErrorReport.CrashInfo crashInfo) {
13458        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13459                UserHandle.getUserId(Binder.getCallingUid()), processName,
13460                r == null ? -1 : r.info.flags,
13461                crashInfo.exceptionClassName,
13462                crashInfo.exceptionMessage,
13463                crashInfo.throwFileName,
13464                crashInfo.throwLineNumber);
13465
13466        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13467
13468        mAppErrors.crashApplication(r, crashInfo);
13469    }
13470
13471    public void handleApplicationStrictModeViolation(
13472            IBinder app,
13473            int violationMask,
13474            StrictMode.ViolationInfo info) {
13475        ProcessRecord r = findAppProcess(app, "StrictMode");
13476        if (r == null) {
13477            return;
13478        }
13479
13480        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13481            Integer stackFingerprint = info.hashCode();
13482            boolean logIt = true;
13483            synchronized (mAlreadyLoggedViolatedStacks) {
13484                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13485                    logIt = false;
13486                    // TODO: sub-sample into EventLog for these, with
13487                    // the info.durationMillis?  Then we'd get
13488                    // the relative pain numbers, without logging all
13489                    // the stack traces repeatedly.  We'd want to do
13490                    // likewise in the client code, which also does
13491                    // dup suppression, before the Binder call.
13492                } else {
13493                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13494                        mAlreadyLoggedViolatedStacks.clear();
13495                    }
13496                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13497                }
13498            }
13499            if (logIt) {
13500                logStrictModeViolationToDropBox(r, info);
13501            }
13502        }
13503
13504        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13505            AppErrorResult result = new AppErrorResult();
13506            synchronized (this) {
13507                final long origId = Binder.clearCallingIdentity();
13508
13509                Message msg = Message.obtain();
13510                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13511                HashMap<String, Object> data = new HashMap<String, Object>();
13512                data.put("result", result);
13513                data.put("app", r);
13514                data.put("violationMask", violationMask);
13515                data.put("info", info);
13516                msg.obj = data;
13517                mUiHandler.sendMessage(msg);
13518
13519                Binder.restoreCallingIdentity(origId);
13520            }
13521            int res = result.get();
13522            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13523        }
13524    }
13525
13526    // Depending on the policy in effect, there could be a bunch of
13527    // these in quick succession so we try to batch these together to
13528    // minimize disk writes, number of dropbox entries, and maximize
13529    // compression, by having more fewer, larger records.
13530    private void logStrictModeViolationToDropBox(
13531            ProcessRecord process,
13532            StrictMode.ViolationInfo info) {
13533        if (info == null) {
13534            return;
13535        }
13536        final boolean isSystemApp = process == null ||
13537                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13538                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13539        final String processName = process == null ? "unknown" : process.processName;
13540        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13541        final DropBoxManager dbox = (DropBoxManager)
13542                mContext.getSystemService(Context.DROPBOX_SERVICE);
13543
13544        // Exit early if the dropbox isn't configured to accept this report type.
13545        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13546
13547        boolean bufferWasEmpty;
13548        boolean needsFlush;
13549        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13550        synchronized (sb) {
13551            bufferWasEmpty = sb.length() == 0;
13552            appendDropBoxProcessHeaders(process, processName, sb);
13553            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13554            sb.append("System-App: ").append(isSystemApp).append("\n");
13555            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13556            if (info.violationNumThisLoop != 0) {
13557                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13558            }
13559            if (info.numAnimationsRunning != 0) {
13560                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13561            }
13562            if (info.broadcastIntentAction != null) {
13563                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13564            }
13565            if (info.durationMillis != -1) {
13566                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13567            }
13568            if (info.numInstances != -1) {
13569                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13570            }
13571            if (info.tags != null) {
13572                for (String tag : info.tags) {
13573                    sb.append("Span-Tag: ").append(tag).append("\n");
13574                }
13575            }
13576            sb.append("\n");
13577            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13578                sb.append(info.crashInfo.stackTrace);
13579                sb.append("\n");
13580            }
13581            if (info.message != null) {
13582                sb.append(info.message);
13583                sb.append("\n");
13584            }
13585
13586            // Only buffer up to ~64k.  Various logging bits truncate
13587            // things at 128k.
13588            needsFlush = (sb.length() > 64 * 1024);
13589        }
13590
13591        // Flush immediately if the buffer's grown too large, or this
13592        // is a non-system app.  Non-system apps are isolated with a
13593        // different tag & policy and not batched.
13594        //
13595        // Batching is useful during internal testing with
13596        // StrictMode settings turned up high.  Without batching,
13597        // thousands of separate files could be created on boot.
13598        if (!isSystemApp || needsFlush) {
13599            new Thread("Error dump: " + dropboxTag) {
13600                @Override
13601                public void run() {
13602                    String report;
13603                    synchronized (sb) {
13604                        report = sb.toString();
13605                        sb.delete(0, sb.length());
13606                        sb.trimToSize();
13607                    }
13608                    if (report.length() != 0) {
13609                        dbox.addText(dropboxTag, report);
13610                    }
13611                }
13612            }.start();
13613            return;
13614        }
13615
13616        // System app batching:
13617        if (!bufferWasEmpty) {
13618            // An existing dropbox-writing thread is outstanding, so
13619            // we don't need to start it up.  The existing thread will
13620            // catch the buffer appends we just did.
13621            return;
13622        }
13623
13624        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13625        // (After this point, we shouldn't access AMS internal data structures.)
13626        new Thread("Error dump: " + dropboxTag) {
13627            @Override
13628            public void run() {
13629                // 5 second sleep to let stacks arrive and be batched together
13630                try {
13631                    Thread.sleep(5000);  // 5 seconds
13632                } catch (InterruptedException e) {}
13633
13634                String errorReport;
13635                synchronized (mStrictModeBuffer) {
13636                    errorReport = mStrictModeBuffer.toString();
13637                    if (errorReport.length() == 0) {
13638                        return;
13639                    }
13640                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13641                    mStrictModeBuffer.trimToSize();
13642                }
13643                dbox.addText(dropboxTag, errorReport);
13644            }
13645        }.start();
13646    }
13647
13648    /**
13649     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13650     * @param app object of the crashing app, null for the system server
13651     * @param tag reported by the caller
13652     * @param system whether this wtf is coming from the system
13653     * @param crashInfo describing the context of the error
13654     * @return true if the process should exit immediately (WTF is fatal)
13655     */
13656    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13657            final ApplicationErrorReport.CrashInfo crashInfo) {
13658        final int callingUid = Binder.getCallingUid();
13659        final int callingPid = Binder.getCallingPid();
13660
13661        if (system) {
13662            // If this is coming from the system, we could very well have low-level
13663            // system locks held, so we want to do this all asynchronously.  And we
13664            // never want this to become fatal, so there is that too.
13665            mHandler.post(new Runnable() {
13666                @Override public void run() {
13667                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13668                }
13669            });
13670            return false;
13671        }
13672
13673        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13674                crashInfo);
13675
13676        if (r != null && r.pid != Process.myPid() &&
13677                Settings.Global.getInt(mContext.getContentResolver(),
13678                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13679            mAppErrors.crashApplication(r, crashInfo);
13680            return true;
13681        } else {
13682            return false;
13683        }
13684    }
13685
13686    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13687            final ApplicationErrorReport.CrashInfo crashInfo) {
13688        final ProcessRecord r = findAppProcess(app, "WTF");
13689        final String processName = app == null ? "system_server"
13690                : (r == null ? "unknown" : r.processName);
13691
13692        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13693                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13694
13695        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13696
13697        return r;
13698    }
13699
13700    /**
13701     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13702     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13703     */
13704    private ProcessRecord findAppProcess(IBinder app, String reason) {
13705        if (app == null) {
13706            return null;
13707        }
13708
13709        synchronized (this) {
13710            final int NP = mProcessNames.getMap().size();
13711            for (int ip=0; ip<NP; ip++) {
13712                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13713                final int NA = apps.size();
13714                for (int ia=0; ia<NA; ia++) {
13715                    ProcessRecord p = apps.valueAt(ia);
13716                    if (p.thread != null && p.thread.asBinder() == app) {
13717                        return p;
13718                    }
13719                }
13720            }
13721
13722            Slog.w(TAG, "Can't find mystery application for " + reason
13723                    + " from pid=" + Binder.getCallingPid()
13724                    + " uid=" + Binder.getCallingUid() + ": " + app);
13725            return null;
13726        }
13727    }
13728
13729    /**
13730     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13731     * to append various headers to the dropbox log text.
13732     */
13733    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13734            StringBuilder sb) {
13735        // Watchdog thread ends up invoking this function (with
13736        // a null ProcessRecord) to add the stack file to dropbox.
13737        // Do not acquire a lock on this (am) in such cases, as it
13738        // could cause a potential deadlock, if and when watchdog
13739        // is invoked due to unavailability of lock on am and it
13740        // would prevent watchdog from killing system_server.
13741        if (process == null) {
13742            sb.append("Process: ").append(processName).append("\n");
13743            return;
13744        }
13745        // Note: ProcessRecord 'process' is guarded by the service
13746        // instance.  (notably process.pkgList, which could otherwise change
13747        // concurrently during execution of this method)
13748        synchronized (this) {
13749            sb.append("Process: ").append(processName).append("\n");
13750            int flags = process.info.flags;
13751            IPackageManager pm = AppGlobals.getPackageManager();
13752            sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
13753            for (int ip=0; ip<process.pkgList.size(); ip++) {
13754                String pkg = process.pkgList.keyAt(ip);
13755                sb.append("Package: ").append(pkg);
13756                try {
13757                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13758                    if (pi != null) {
13759                        sb.append(" v").append(pi.versionCode);
13760                        if (pi.versionName != null) {
13761                            sb.append(" (").append(pi.versionName).append(")");
13762                        }
13763                    }
13764                } catch (RemoteException e) {
13765                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13766                }
13767                sb.append("\n");
13768            }
13769        }
13770    }
13771
13772    private static String processClass(ProcessRecord process) {
13773        if (process == null || process.pid == MY_PID) {
13774            return "system_server";
13775        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13776            return "system_app";
13777        } else {
13778            return "data_app";
13779        }
13780    }
13781
13782    private volatile long mWtfClusterStart;
13783    private volatile int mWtfClusterCount;
13784
13785    /**
13786     * Write a description of an error (crash, WTF, ANR) to the drop box.
13787     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13788     * @param process which caused the error, null means the system server
13789     * @param activity which triggered the error, null if unknown
13790     * @param parent activity related to the error, null if unknown
13791     * @param subject line related to the error, null if absent
13792     * @param report in long form describing the error, null if absent
13793     * @param dataFile text file to include in the report, null if none
13794     * @param crashInfo giving an application stack trace, null if absent
13795     */
13796    public void addErrorToDropBox(String eventType,
13797            ProcessRecord process, String processName, ActivityRecord activity,
13798            ActivityRecord parent, String subject,
13799            final String report, final File dataFile,
13800            final ApplicationErrorReport.CrashInfo crashInfo) {
13801        // NOTE -- this must never acquire the ActivityManagerService lock,
13802        // otherwise the watchdog may be prevented from resetting the system.
13803
13804        final String dropboxTag = processClass(process) + "_" + eventType;
13805        final DropBoxManager dbox = (DropBoxManager)
13806                mContext.getSystemService(Context.DROPBOX_SERVICE);
13807
13808        // Exit early if the dropbox isn't configured to accept this report type.
13809        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13810
13811        // Rate-limit how often we're willing to do the heavy lifting below to
13812        // collect and record logs; currently 5 logs per 10 second period.
13813        final long now = SystemClock.elapsedRealtime();
13814        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13815            mWtfClusterStart = now;
13816            mWtfClusterCount = 1;
13817        } else {
13818            if (mWtfClusterCount++ >= 5) return;
13819        }
13820
13821        final StringBuilder sb = new StringBuilder(1024);
13822        appendDropBoxProcessHeaders(process, processName, sb);
13823        if (process != null) {
13824            sb.append("Foreground: ")
13825                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13826                    .append("\n");
13827        }
13828        if (activity != null) {
13829            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13830        }
13831        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13832            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13833        }
13834        if (parent != null && parent != activity) {
13835            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13836        }
13837        if (subject != null) {
13838            sb.append("Subject: ").append(subject).append("\n");
13839        }
13840        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13841        if (Debug.isDebuggerConnected()) {
13842            sb.append("Debugger: Connected\n");
13843        }
13844        sb.append("\n");
13845
13846        // Do the rest in a worker thread to avoid blocking the caller on I/O
13847        // (After this point, we shouldn't access AMS internal data structures.)
13848        Thread worker = new Thread("Error dump: " + dropboxTag) {
13849            @Override
13850            public void run() {
13851                if (report != null) {
13852                    sb.append(report);
13853                }
13854
13855                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13856                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13857                int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
13858                        - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
13859
13860                if (dataFile != null && maxDataFileSize > 0) {
13861                    try {
13862                        sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
13863                                    "\n\n[[TRUNCATED]]"));
13864                    } catch (IOException e) {
13865                        Slog.e(TAG, "Error reading " + dataFile, e);
13866                    }
13867                }
13868                if (crashInfo != null && crashInfo.stackTrace != null) {
13869                    sb.append(crashInfo.stackTrace);
13870                }
13871
13872                if (lines > 0) {
13873                    sb.append("\n");
13874
13875                    // Merge several logcat streams, and take the last N lines
13876                    InputStreamReader input = null;
13877                    try {
13878                        java.lang.Process logcat = new ProcessBuilder(
13879                                "/system/bin/timeout", "-k", "15s", "10s",
13880                                "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
13881                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13882                                        .redirectErrorStream(true).start();
13883
13884                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13885                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13886                        input = new InputStreamReader(logcat.getInputStream());
13887
13888                        int num;
13889                        char[] buf = new char[8192];
13890                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13891                    } catch (IOException e) {
13892                        Slog.e(TAG, "Error running logcat", e);
13893                    } finally {
13894                        if (input != null) try { input.close(); } catch (IOException e) {}
13895                    }
13896                }
13897
13898                dbox.addText(dropboxTag, sb.toString());
13899            }
13900        };
13901
13902        if (process == null) {
13903            // If process is null, we are being called from some internal code
13904            // and may be about to die -- run this synchronously.
13905            worker.run();
13906        } else {
13907            worker.start();
13908        }
13909    }
13910
13911    @Override
13912    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13913        enforceNotIsolatedCaller("getProcessesInErrorState");
13914        // assume our apps are happy - lazy create the list
13915        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13916
13917        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13918                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13919        int userId = UserHandle.getUserId(Binder.getCallingUid());
13920
13921        synchronized (this) {
13922
13923            // iterate across all processes
13924            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13925                ProcessRecord app = mLruProcesses.get(i);
13926                if (!allUsers && app.userId != userId) {
13927                    continue;
13928                }
13929                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13930                    // This one's in trouble, so we'll generate a report for it
13931                    // crashes are higher priority (in case there's a crash *and* an anr)
13932                    ActivityManager.ProcessErrorStateInfo report = null;
13933                    if (app.crashing) {
13934                        report = app.crashingReport;
13935                    } else if (app.notResponding) {
13936                        report = app.notRespondingReport;
13937                    }
13938
13939                    if (report != null) {
13940                        if (errList == null) {
13941                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13942                        }
13943                        errList.add(report);
13944                    } else {
13945                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13946                                " crashing = " + app.crashing +
13947                                " notResponding = " + app.notResponding);
13948                    }
13949                }
13950            }
13951        }
13952
13953        return errList;
13954    }
13955
13956    static int procStateToImportance(int procState, int memAdj,
13957            ActivityManager.RunningAppProcessInfo currApp) {
13958        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13959        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13960            currApp.lru = memAdj;
13961        } else {
13962            currApp.lru = 0;
13963        }
13964        return imp;
13965    }
13966
13967    private void fillInProcMemInfo(ProcessRecord app,
13968            ActivityManager.RunningAppProcessInfo outInfo) {
13969        outInfo.pid = app.pid;
13970        outInfo.uid = app.info.uid;
13971        if (mHeavyWeightProcess == app) {
13972            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13973        }
13974        if (app.persistent) {
13975            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13976        }
13977        if (app.activities.size() > 0) {
13978            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13979        }
13980        outInfo.lastTrimLevel = app.trimMemoryLevel;
13981        int adj = app.curAdj;
13982        int procState = app.curProcState;
13983        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13984        outInfo.importanceReasonCode = app.adjTypeCode;
13985        outInfo.processState = app.curProcState;
13986    }
13987
13988    @Override
13989    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13990        enforceNotIsolatedCaller("getRunningAppProcesses");
13991
13992        final int callingUid = Binder.getCallingUid();
13993
13994        // Lazy instantiation of list
13995        List<ActivityManager.RunningAppProcessInfo> runList = null;
13996        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13997                callingUid) == PackageManager.PERMISSION_GRANTED;
13998        final int userId = UserHandle.getUserId(callingUid);
13999        final boolean allUids = isGetTasksAllowed(
14000                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
14001
14002        synchronized (this) {
14003            // Iterate across all processes
14004            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14005                ProcessRecord app = mLruProcesses.get(i);
14006                if ((!allUsers && app.userId != userId)
14007                        || (!allUids && app.uid != callingUid)) {
14008                    continue;
14009                }
14010                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
14011                    // Generate process state info for running application
14012                    ActivityManager.RunningAppProcessInfo currApp =
14013                        new ActivityManager.RunningAppProcessInfo(app.processName,
14014                                app.pid, app.getPackageList());
14015                    fillInProcMemInfo(app, currApp);
14016                    if (app.adjSource instanceof ProcessRecord) {
14017                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
14018                        currApp.importanceReasonImportance =
14019                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
14020                                        app.adjSourceProcState);
14021                    } else if (app.adjSource instanceof ActivityRecord) {
14022                        ActivityRecord r = (ActivityRecord)app.adjSource;
14023                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
14024                    }
14025                    if (app.adjTarget instanceof ComponentName) {
14026                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
14027                    }
14028                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
14029                    //        + " lru=" + currApp.lru);
14030                    if (runList == null) {
14031                        runList = new ArrayList<>();
14032                    }
14033                    runList.add(currApp);
14034                }
14035            }
14036        }
14037        return runList;
14038    }
14039
14040    @Override
14041    public List<ApplicationInfo> getRunningExternalApplications() {
14042        enforceNotIsolatedCaller("getRunningExternalApplications");
14043        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
14044        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
14045        if (runningApps != null && runningApps.size() > 0) {
14046            Set<String> extList = new HashSet<String>();
14047            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
14048                if (app.pkgList != null) {
14049                    for (String pkg : app.pkgList) {
14050                        extList.add(pkg);
14051                    }
14052                }
14053            }
14054            IPackageManager pm = AppGlobals.getPackageManager();
14055            for (String pkg : extList) {
14056                try {
14057                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
14058                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
14059                        retList.add(info);
14060                    }
14061                } catch (RemoteException e) {
14062                }
14063            }
14064        }
14065        return retList;
14066    }
14067
14068    @Override
14069    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
14070        enforceNotIsolatedCaller("getMyMemoryState");
14071        synchronized (this) {
14072            ProcessRecord proc;
14073            synchronized (mPidsSelfLocked) {
14074                proc = mPidsSelfLocked.get(Binder.getCallingPid());
14075            }
14076            fillInProcMemInfo(proc, outInfo);
14077        }
14078    }
14079
14080    @Override
14081    public int getMemoryTrimLevel() {
14082        enforceNotIsolatedCaller("getMyMemoryState");
14083        synchronized (this) {
14084            return mLastMemoryLevel;
14085        }
14086    }
14087
14088    @Override
14089    public void onShellCommand(FileDescriptor in, FileDescriptor out,
14090            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
14091        (new ActivityManagerShellCommand(this, false)).exec(
14092                this, in, out, err, args, resultReceiver);
14093    }
14094
14095    @Override
14096    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
14097        if (checkCallingPermission(android.Manifest.permission.DUMP)
14098                != PackageManager.PERMISSION_GRANTED) {
14099            pw.println("Permission Denial: can't dump ActivityManager from from pid="
14100                    + Binder.getCallingPid()
14101                    + ", uid=" + Binder.getCallingUid()
14102                    + " without permission "
14103                    + android.Manifest.permission.DUMP);
14104            return;
14105        }
14106
14107        boolean dumpAll = false;
14108        boolean dumpClient = false;
14109        boolean dumpCheckin = false;
14110        boolean dumpCheckinFormat = false;
14111        String dumpPackage = null;
14112
14113        int opti = 0;
14114        while (opti < args.length) {
14115            String opt = args[opti];
14116            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14117                break;
14118            }
14119            opti++;
14120            if ("-a".equals(opt)) {
14121                dumpAll = true;
14122            } else if ("-c".equals(opt)) {
14123                dumpClient = true;
14124            } else if ("-p".equals(opt)) {
14125                if (opti < args.length) {
14126                    dumpPackage = args[opti];
14127                    opti++;
14128                } else {
14129                    pw.println("Error: -p option requires package argument");
14130                    return;
14131                }
14132                dumpClient = true;
14133            } else if ("--checkin".equals(opt)) {
14134                dumpCheckin = dumpCheckinFormat = true;
14135            } else if ("-C".equals(opt)) {
14136                dumpCheckinFormat = true;
14137            } else if ("-h".equals(opt)) {
14138                ActivityManagerShellCommand.dumpHelp(pw, true);
14139                return;
14140            } else {
14141                pw.println("Unknown argument: " + opt + "; use -h for help");
14142            }
14143        }
14144
14145        long origId = Binder.clearCallingIdentity();
14146        boolean more = false;
14147        // Is the caller requesting to dump a particular piece of data?
14148        if (opti < args.length) {
14149            String cmd = args[opti];
14150            opti++;
14151            if ("activities".equals(cmd) || "a".equals(cmd)) {
14152                synchronized (this) {
14153                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14154                }
14155            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
14156                synchronized (this) {
14157                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
14158                }
14159            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
14160                String[] newArgs;
14161                String name;
14162                if (opti >= args.length) {
14163                    name = null;
14164                    newArgs = EMPTY_STRING_ARRAY;
14165                } else {
14166                    dumpPackage = args[opti];
14167                    opti++;
14168                    newArgs = new String[args.length - opti];
14169                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14170                            args.length - opti);
14171                }
14172                synchronized (this) {
14173                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
14174                }
14175            } else if ("broadcast-stats".equals(cmd)) {
14176                String[] newArgs;
14177                String name;
14178                if (opti >= args.length) {
14179                    name = null;
14180                    newArgs = EMPTY_STRING_ARRAY;
14181                } else {
14182                    dumpPackage = args[opti];
14183                    opti++;
14184                    newArgs = new String[args.length - opti];
14185                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14186                            args.length - opti);
14187                }
14188                synchronized (this) {
14189                    if (dumpCheckinFormat) {
14190                        dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
14191                                dumpPackage);
14192                    } else {
14193                        dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
14194                    }
14195                }
14196            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
14197                String[] newArgs;
14198                String name;
14199                if (opti >= args.length) {
14200                    name = null;
14201                    newArgs = EMPTY_STRING_ARRAY;
14202                } else {
14203                    dumpPackage = args[opti];
14204                    opti++;
14205                    newArgs = new String[args.length - opti];
14206                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14207                            args.length - opti);
14208                }
14209                synchronized (this) {
14210                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
14211                }
14212            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
14213                String[] newArgs;
14214                String name;
14215                if (opti >= args.length) {
14216                    name = null;
14217                    newArgs = EMPTY_STRING_ARRAY;
14218                } else {
14219                    dumpPackage = args[opti];
14220                    opti++;
14221                    newArgs = new String[args.length - opti];
14222                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14223                            args.length - opti);
14224                }
14225                synchronized (this) {
14226                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
14227                }
14228            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
14229                synchronized (this) {
14230                    dumpOomLocked(fd, pw, args, opti, true);
14231                }
14232            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
14233                synchronized (this) {
14234                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
14235                }
14236            } else if ("provider".equals(cmd)) {
14237                String[] newArgs;
14238                String name;
14239                if (opti >= args.length) {
14240                    name = null;
14241                    newArgs = EMPTY_STRING_ARRAY;
14242                } else {
14243                    name = args[opti];
14244                    opti++;
14245                    newArgs = new String[args.length - opti];
14246                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14247                }
14248                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
14249                    pw.println("No providers match: " + name);
14250                    pw.println("Use -h for help.");
14251                }
14252            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
14253                synchronized (this) {
14254                    dumpProvidersLocked(fd, pw, args, opti, true, null);
14255                }
14256            } else if ("service".equals(cmd)) {
14257                String[] newArgs;
14258                String name;
14259                if (opti >= args.length) {
14260                    name = null;
14261                    newArgs = EMPTY_STRING_ARRAY;
14262                } else {
14263                    name = args[opti];
14264                    opti++;
14265                    newArgs = new String[args.length - opti];
14266                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14267                            args.length - opti);
14268                }
14269                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
14270                    pw.println("No services match: " + name);
14271                    pw.println("Use -h for help.");
14272                }
14273            } else if ("package".equals(cmd)) {
14274                String[] newArgs;
14275                if (opti >= args.length) {
14276                    pw.println("package: no package name specified");
14277                    pw.println("Use -h for help.");
14278                } else {
14279                    dumpPackage = args[opti];
14280                    opti++;
14281                    newArgs = new String[args.length - opti];
14282                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14283                            args.length - opti);
14284                    args = newArgs;
14285                    opti = 0;
14286                    more = true;
14287                }
14288            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
14289                synchronized (this) {
14290                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14291                }
14292            } else if ("services".equals(cmd) || "s".equals(cmd)) {
14293                if (dumpClient) {
14294                    ActiveServices.ServiceDumper dumper;
14295                    synchronized (this) {
14296                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14297                                dumpPackage);
14298                    }
14299                    dumper.dumpWithClient();
14300                } else {
14301                    synchronized (this) {
14302                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14303                                dumpPackage).dumpLocked();
14304                    }
14305                }
14306            } else if ("locks".equals(cmd)) {
14307                LockGuard.dump(fd, pw, args);
14308            } else {
14309                // Dumping a single activity?
14310                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
14311                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
14312                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
14313                    if (res < 0) {
14314                        pw.println("Bad activity command, or no activities match: " + cmd);
14315                        pw.println("Use -h for help.");
14316                    }
14317                }
14318            }
14319            if (!more) {
14320                Binder.restoreCallingIdentity(origId);
14321                return;
14322            }
14323        }
14324
14325        // No piece of data specified, dump everything.
14326        if (dumpCheckinFormat) {
14327            dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
14328        } else if (dumpClient) {
14329            ActiveServices.ServiceDumper sdumper;
14330            synchronized (this) {
14331                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14332                pw.println();
14333                if (dumpAll) {
14334                    pw.println("-------------------------------------------------------------------------------");
14335                }
14336                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14337                pw.println();
14338                if (dumpAll) {
14339                    pw.println("-------------------------------------------------------------------------------");
14340                }
14341                if (dumpAll || dumpPackage != null) {
14342                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14343                    pw.println();
14344                    if (dumpAll) {
14345                        pw.println("-------------------------------------------------------------------------------");
14346                    }
14347                }
14348                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14349                pw.println();
14350                if (dumpAll) {
14351                    pw.println("-------------------------------------------------------------------------------");
14352                }
14353                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14354                pw.println();
14355                if (dumpAll) {
14356                    pw.println("-------------------------------------------------------------------------------");
14357                }
14358                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
14359                        dumpPackage);
14360            }
14361            sdumper.dumpWithClient();
14362            pw.println();
14363            synchronized (this) {
14364                if (dumpAll) {
14365                    pw.println("-------------------------------------------------------------------------------");
14366                }
14367                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14368                pw.println();
14369                if (dumpAll) {
14370                    pw.println("-------------------------------------------------------------------------------");
14371                }
14372                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14373                if (mAssociations.size() > 0) {
14374                    pw.println();
14375                    if (dumpAll) {
14376                        pw.println("-------------------------------------------------------------------------------");
14377                    }
14378                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14379                }
14380                pw.println();
14381                if (dumpAll) {
14382                    pw.println("-------------------------------------------------------------------------------");
14383                }
14384                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14385            }
14386
14387        } else {
14388            synchronized (this) {
14389                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14390                pw.println();
14391                if (dumpAll) {
14392                    pw.println("-------------------------------------------------------------------------------");
14393                }
14394                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14395                pw.println();
14396                if (dumpAll) {
14397                    pw.println("-------------------------------------------------------------------------------");
14398                }
14399                if (dumpAll || dumpPackage != null) {
14400                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14401                    pw.println();
14402                    if (dumpAll) {
14403                        pw.println("-------------------------------------------------------------------------------");
14404                    }
14405                }
14406                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14407                pw.println();
14408                if (dumpAll) {
14409                    pw.println("-------------------------------------------------------------------------------");
14410                }
14411                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14412                pw.println();
14413                if (dumpAll) {
14414                    pw.println("-------------------------------------------------------------------------------");
14415                }
14416                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
14417                        .dumpLocked();
14418                pw.println();
14419                if (dumpAll) {
14420                    pw.println("-------------------------------------------------------------------------------");
14421                }
14422                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14423                pw.println();
14424                if (dumpAll) {
14425                    pw.println("-------------------------------------------------------------------------------");
14426                }
14427                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14428                if (mAssociations.size() > 0) {
14429                    pw.println();
14430                    if (dumpAll) {
14431                        pw.println("-------------------------------------------------------------------------------");
14432                    }
14433                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14434                }
14435                pw.println();
14436                if (dumpAll) {
14437                    pw.println("-------------------------------------------------------------------------------");
14438                }
14439                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14440            }
14441        }
14442        Binder.restoreCallingIdentity(origId);
14443    }
14444
14445    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14446            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14447        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
14448
14449        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
14450                dumpPackage);
14451        boolean needSep = printedAnything;
14452
14453        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
14454                dumpPackage, needSep, "  mFocusedActivity: ");
14455        if (printed) {
14456            printedAnything = true;
14457            needSep = false;
14458        }
14459
14460        if (dumpPackage == null) {
14461            if (needSep) {
14462                pw.println();
14463            }
14464            needSep = true;
14465            printedAnything = true;
14466            mStackSupervisor.dump(pw, "  ");
14467        }
14468
14469        if (!printedAnything) {
14470            pw.println("  (nothing)");
14471        }
14472    }
14473
14474    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14475            int opti, boolean dumpAll, String dumpPackage) {
14476        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14477
14478        boolean printedAnything = false;
14479
14480        if (mRecentTasks != null && mRecentTasks.size() > 0) {
14481            boolean printedHeader = false;
14482
14483            final int N = mRecentTasks.size();
14484            for (int i=0; i<N; i++) {
14485                TaskRecord tr = mRecentTasks.get(i);
14486                if (dumpPackage != null) {
14487                    if (tr.realActivity == null ||
14488                            !dumpPackage.equals(tr.realActivity)) {
14489                        continue;
14490                    }
14491                }
14492                if (!printedHeader) {
14493                    pw.println("  Recent tasks:");
14494                    printedHeader = true;
14495                    printedAnything = true;
14496                }
14497                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
14498                        pw.println(tr);
14499                if (dumpAll) {
14500                    mRecentTasks.get(i).dump(pw, "    ");
14501                }
14502            }
14503        }
14504
14505        if (!printedAnything) {
14506            pw.println("  (nothing)");
14507        }
14508    }
14509
14510    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14511            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14512        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14513
14514        int dumpUid = 0;
14515        if (dumpPackage != null) {
14516            IPackageManager pm = AppGlobals.getPackageManager();
14517            try {
14518                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
14519            } catch (RemoteException e) {
14520            }
14521        }
14522
14523        boolean printedAnything = false;
14524
14525        final long now = SystemClock.uptimeMillis();
14526
14527        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14528            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14529                    = mAssociations.valueAt(i1);
14530            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14531                SparseArray<ArrayMap<String, Association>> sourceUids
14532                        = targetComponents.valueAt(i2);
14533                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14534                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14535                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14536                        Association ass = sourceProcesses.valueAt(i4);
14537                        if (dumpPackage != null) {
14538                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14539                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14540                                continue;
14541                            }
14542                        }
14543                        printedAnything = true;
14544                        pw.print("  ");
14545                        pw.print(ass.mTargetProcess);
14546                        pw.print("/");
14547                        UserHandle.formatUid(pw, ass.mTargetUid);
14548                        pw.print(" <- ");
14549                        pw.print(ass.mSourceProcess);
14550                        pw.print("/");
14551                        UserHandle.formatUid(pw, ass.mSourceUid);
14552                        pw.println();
14553                        pw.print("    via ");
14554                        pw.print(ass.mTargetComponent.flattenToShortString());
14555                        pw.println();
14556                        pw.print("    ");
14557                        long dur = ass.mTime;
14558                        if (ass.mNesting > 0) {
14559                            dur += now - ass.mStartTime;
14560                        }
14561                        TimeUtils.formatDuration(dur, pw);
14562                        pw.print(" (");
14563                        pw.print(ass.mCount);
14564                        pw.print(" times)");
14565                        pw.print("  ");
14566                        for (int i=0; i<ass.mStateTimes.length; i++) {
14567                            long amt = ass.mStateTimes[i];
14568                            if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14569                                amt += now - ass.mLastStateUptime;
14570                            }
14571                            if (amt != 0) {
14572                                pw.print(" ");
14573                                pw.print(ProcessList.makeProcStateString(
14574                                            i + ActivityManager.MIN_PROCESS_STATE));
14575                                pw.print("=");
14576                                TimeUtils.formatDuration(amt, pw);
14577                                if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14578                                    pw.print("*");
14579                                }
14580                            }
14581                        }
14582                        pw.println();
14583                        if (ass.mNesting > 0) {
14584                            pw.print("    Currently active: ");
14585                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
14586                            pw.println();
14587                        }
14588                    }
14589                }
14590            }
14591
14592        }
14593
14594        if (!printedAnything) {
14595            pw.println("  (nothing)");
14596        }
14597    }
14598
14599    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14600            String header, boolean needSep) {
14601        boolean printed = false;
14602        int whichAppId = -1;
14603        if (dumpPackage != null) {
14604            try {
14605                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14606                        dumpPackage, 0);
14607                whichAppId = UserHandle.getAppId(info.uid);
14608            } catch (NameNotFoundException e) {
14609                e.printStackTrace();
14610            }
14611        }
14612        for (int i=0; i<uids.size(); i++) {
14613            UidRecord uidRec = uids.valueAt(i);
14614            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14615                continue;
14616            }
14617            if (!printed) {
14618                printed = true;
14619                if (needSep) {
14620                    pw.println();
14621                }
14622                pw.print("  ");
14623                pw.println(header);
14624                needSep = true;
14625            }
14626            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14627            pw.print(": "); pw.println(uidRec);
14628        }
14629        return printed;
14630    }
14631
14632    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14633            int opti, boolean dumpAll, String dumpPackage) {
14634        boolean needSep = false;
14635        boolean printedAnything = false;
14636        int numPers = 0;
14637
14638        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14639
14640        if (dumpAll) {
14641            final int NP = mProcessNames.getMap().size();
14642            for (int ip=0; ip<NP; ip++) {
14643                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14644                final int NA = procs.size();
14645                for (int ia=0; ia<NA; ia++) {
14646                    ProcessRecord r = procs.valueAt(ia);
14647                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14648                        continue;
14649                    }
14650                    if (!needSep) {
14651                        pw.println("  All known processes:");
14652                        needSep = true;
14653                        printedAnything = true;
14654                    }
14655                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14656                        pw.print(" UID "); pw.print(procs.keyAt(ia));
14657                        pw.print(" "); pw.println(r);
14658                    r.dump(pw, "    ");
14659                    if (r.persistent) {
14660                        numPers++;
14661                    }
14662                }
14663            }
14664        }
14665
14666        if (mIsolatedProcesses.size() > 0) {
14667            boolean printed = false;
14668            for (int i=0; i<mIsolatedProcesses.size(); i++) {
14669                ProcessRecord r = mIsolatedProcesses.valueAt(i);
14670                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14671                    continue;
14672                }
14673                if (!printed) {
14674                    if (needSep) {
14675                        pw.println();
14676                    }
14677                    pw.println("  Isolated process list (sorted by uid):");
14678                    printedAnything = true;
14679                    printed = true;
14680                    needSep = true;
14681                }
14682                pw.println(String.format("%sIsolated #%2d: %s",
14683                        "    ", i, r.toString()));
14684            }
14685        }
14686
14687        if (mActiveUids.size() > 0) {
14688            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14689                printedAnything = needSep = true;
14690            }
14691        }
14692        if (mValidateUids.size() > 0) {
14693            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14694                printedAnything = needSep = true;
14695            }
14696        }
14697
14698        if (mLruProcesses.size() > 0) {
14699            if (needSep) {
14700                pw.println();
14701            }
14702            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14703                    pw.print(" total, non-act at ");
14704                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14705                    pw.print(", non-svc at ");
14706                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14707                    pw.println("):");
14708            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14709            needSep = true;
14710            printedAnything = true;
14711        }
14712
14713        if (dumpAll || dumpPackage != null) {
14714            synchronized (mPidsSelfLocked) {
14715                boolean printed = false;
14716                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14717                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14718                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14719                        continue;
14720                    }
14721                    if (!printed) {
14722                        if (needSep) pw.println();
14723                        needSep = true;
14724                        pw.println("  PID mappings:");
14725                        printed = true;
14726                        printedAnything = true;
14727                    }
14728                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14729                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14730                }
14731            }
14732        }
14733
14734        if (mForegroundProcesses.size() > 0) {
14735            synchronized (mPidsSelfLocked) {
14736                boolean printed = false;
14737                for (int i=0; i<mForegroundProcesses.size(); i++) {
14738                    ProcessRecord r = mPidsSelfLocked.get(
14739                            mForegroundProcesses.valueAt(i).pid);
14740                    if (dumpPackage != null && (r == null
14741                            || !r.pkgList.containsKey(dumpPackage))) {
14742                        continue;
14743                    }
14744                    if (!printed) {
14745                        if (needSep) pw.println();
14746                        needSep = true;
14747                        pw.println("  Foreground Processes:");
14748                        printed = true;
14749                        printedAnything = true;
14750                    }
14751                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14752                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14753                }
14754            }
14755        }
14756
14757        if (mPersistentStartingProcesses.size() > 0) {
14758            if (needSep) pw.println();
14759            needSep = true;
14760            printedAnything = true;
14761            pw.println("  Persisent processes that are starting:");
14762            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14763                    "Starting Norm", "Restarting PERS", dumpPackage);
14764        }
14765
14766        if (mRemovedProcesses.size() > 0) {
14767            if (needSep) pw.println();
14768            needSep = true;
14769            printedAnything = true;
14770            pw.println("  Processes that are being removed:");
14771            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14772                    "Removed Norm", "Removed PERS", dumpPackage);
14773        }
14774
14775        if (mProcessesOnHold.size() > 0) {
14776            if (needSep) pw.println();
14777            needSep = true;
14778            printedAnything = true;
14779            pw.println("  Processes that are on old until the system is ready:");
14780            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14781                    "OnHold Norm", "OnHold PERS", dumpPackage);
14782        }
14783
14784        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14785
14786        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14787        if (needSep) {
14788            printedAnything = true;
14789        }
14790
14791        if (dumpPackage == null) {
14792            pw.println();
14793            needSep = false;
14794            mUserController.dump(pw, dumpAll);
14795        }
14796        if (mHomeProcess != null && (dumpPackage == null
14797                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14798            if (needSep) {
14799                pw.println();
14800                needSep = false;
14801            }
14802            pw.println("  mHomeProcess: " + mHomeProcess);
14803        }
14804        if (mPreviousProcess != null && (dumpPackage == null
14805                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14806            if (needSep) {
14807                pw.println();
14808                needSep = false;
14809            }
14810            pw.println("  mPreviousProcess: " + mPreviousProcess);
14811        }
14812        if (dumpAll) {
14813            StringBuilder sb = new StringBuilder(128);
14814            sb.append("  mPreviousProcessVisibleTime: ");
14815            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14816            pw.println(sb);
14817        }
14818        if (mHeavyWeightProcess != null && (dumpPackage == null
14819                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14820            if (needSep) {
14821                pw.println();
14822                needSep = false;
14823            }
14824            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14825        }
14826        if (dumpPackage == null) {
14827            pw.println("  mConfiguration: " + mConfiguration);
14828        }
14829        if (dumpAll) {
14830            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14831            if (mCompatModePackages.getPackages().size() > 0) {
14832                boolean printed = false;
14833                for (Map.Entry<String, Integer> entry
14834                        : mCompatModePackages.getPackages().entrySet()) {
14835                    String pkg = entry.getKey();
14836                    int mode = entry.getValue();
14837                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14838                        continue;
14839                    }
14840                    if (!printed) {
14841                        pw.println("  mScreenCompatPackages:");
14842                        printed = true;
14843                    }
14844                    pw.print("    "); pw.print(pkg); pw.print(": ");
14845                            pw.print(mode); pw.println();
14846                }
14847            }
14848        }
14849        if (dumpPackage == null) {
14850            pw.println("  mWakefulness="
14851                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14852            pw.println("  mSleepTokens=" + mSleepTokens);
14853            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14854                    + lockScreenShownToString());
14855            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14856            if (mRunningVoice != null) {
14857                pw.println("  mRunningVoice=" + mRunningVoice);
14858                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14859            }
14860        }
14861        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14862                || mOrigWaitForDebugger) {
14863            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14864                    || dumpPackage.equals(mOrigDebugApp)) {
14865                if (needSep) {
14866                    pw.println();
14867                    needSep = false;
14868                }
14869                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14870                        + " mDebugTransient=" + mDebugTransient
14871                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14872            }
14873        }
14874        if (mCurAppTimeTracker != null) {
14875            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14876        }
14877        if (mMemWatchProcesses.getMap().size() > 0) {
14878            pw.println("  Mem watch processes:");
14879            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14880                    = mMemWatchProcesses.getMap();
14881            for (int i=0; i<procs.size(); i++) {
14882                final String proc = procs.keyAt(i);
14883                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14884                for (int j=0; j<uids.size(); j++) {
14885                    if (needSep) {
14886                        pw.println();
14887                        needSep = false;
14888                    }
14889                    StringBuilder sb = new StringBuilder();
14890                    sb.append("    ").append(proc).append('/');
14891                    UserHandle.formatUid(sb, uids.keyAt(j));
14892                    Pair<Long, String> val = uids.valueAt(j);
14893                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14894                    if (val.second != null) {
14895                        sb.append(", report to ").append(val.second);
14896                    }
14897                    pw.println(sb.toString());
14898                }
14899            }
14900            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14901            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14902            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14903                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14904        }
14905        if (mTrackAllocationApp != null) {
14906            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14907                if (needSep) {
14908                    pw.println();
14909                    needSep = false;
14910                }
14911                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14912            }
14913        }
14914        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14915                || mProfileFd != null) {
14916            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14917                if (needSep) {
14918                    pw.println();
14919                    needSep = false;
14920                }
14921                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14922                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14923                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14924                        + mAutoStopProfiler);
14925                pw.println("  mProfileType=" + mProfileType);
14926            }
14927        }
14928        if (mNativeDebuggingApp != null) {
14929            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14930                if (needSep) {
14931                    pw.println();
14932                    needSep = false;
14933                }
14934                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14935            }
14936        }
14937        if (dumpPackage == null) {
14938            if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14939                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14940                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14941            }
14942            if (mController != null) {
14943                pw.println("  mController=" + mController
14944                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14945            }
14946            if (dumpAll) {
14947                pw.println("  Total persistent processes: " + numPers);
14948                pw.println("  mProcessesReady=" + mProcessesReady
14949                        + " mSystemReady=" + mSystemReady
14950                        + " mBooted=" + mBooted
14951                        + " mFactoryTest=" + mFactoryTest);
14952                pw.println("  mBooting=" + mBooting
14953                        + " mCallFinishBooting=" + mCallFinishBooting
14954                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14955                pw.print("  mLastPowerCheckRealtime=");
14956                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14957                        pw.println("");
14958                pw.print("  mLastPowerCheckUptime=");
14959                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14960                        pw.println("");
14961                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14962                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14963                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14964                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14965                        + " (" + mLruProcesses.size() + " total)"
14966                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14967                        + " mNumServiceProcs=" + mNumServiceProcs
14968                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14969                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14970                        + " mLastMemoryLevel=" + mLastMemoryLevel
14971                        + " mLastNumProcesses=" + mLastNumProcesses);
14972                long now = SystemClock.uptimeMillis();
14973                pw.print("  mLastIdleTime=");
14974                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14975                        pw.print(" mLowRamSinceLastIdle=");
14976                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14977                        pw.println();
14978            }
14979        }
14980
14981        if (!printedAnything) {
14982            pw.println("  (nothing)");
14983        }
14984    }
14985
14986    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14987            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14988        if (mProcessesToGc.size() > 0) {
14989            boolean printed = false;
14990            long now = SystemClock.uptimeMillis();
14991            for (int i=0; i<mProcessesToGc.size(); i++) {
14992                ProcessRecord proc = mProcessesToGc.get(i);
14993                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14994                    continue;
14995                }
14996                if (!printed) {
14997                    if (needSep) pw.println();
14998                    needSep = true;
14999                    pw.println("  Processes that are waiting to GC:");
15000                    printed = true;
15001                }
15002                pw.print("    Process "); pw.println(proc);
15003                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
15004                        pw.print(", last gced=");
15005                        pw.print(now-proc.lastRequestedGc);
15006                        pw.print(" ms ago, last lowMem=");
15007                        pw.print(now-proc.lastLowMemory);
15008                        pw.println(" ms ago");
15009
15010            }
15011        }
15012        return needSep;
15013    }
15014
15015    void printOomLevel(PrintWriter pw, String name, int adj) {
15016        pw.print("    ");
15017        if (adj >= 0) {
15018            pw.print(' ');
15019            if (adj < 10) pw.print(' ');
15020        } else {
15021            if (adj > -10) pw.print(' ');
15022        }
15023        pw.print(adj);
15024        pw.print(": ");
15025        pw.print(name);
15026        pw.print(" (");
15027        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
15028        pw.println(")");
15029    }
15030
15031    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15032            int opti, boolean dumpAll) {
15033        boolean needSep = false;
15034
15035        if (mLruProcesses.size() > 0) {
15036            if (needSep) pw.println();
15037            needSep = true;
15038            pw.println("  OOM levels:");
15039            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
15040            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
15041            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
15042            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
15043            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
15044            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
15045            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
15046            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
15047            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
15048            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
15049            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
15050            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
15051            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
15052            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
15053
15054            if (needSep) pw.println();
15055            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
15056                    pw.print(" total, non-act at ");
15057                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15058                    pw.print(", non-svc at ");
15059                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15060                    pw.println("):");
15061            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
15062            needSep = true;
15063        }
15064
15065        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
15066
15067        pw.println();
15068        pw.println("  mHomeProcess: " + mHomeProcess);
15069        pw.println("  mPreviousProcess: " + mPreviousProcess);
15070        if (mHeavyWeightProcess != null) {
15071            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
15072        }
15073
15074        return true;
15075    }
15076
15077    /**
15078     * There are three ways to call this:
15079     *  - no provider specified: dump all the providers
15080     *  - a flattened component name that matched an existing provider was specified as the
15081     *    first arg: dump that one provider
15082     *  - the first arg isn't the flattened component name of an existing provider:
15083     *    dump all providers whose component contains the first arg as a substring
15084     */
15085    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15086            int opti, boolean dumpAll) {
15087        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
15088    }
15089
15090    static class ItemMatcher {
15091        ArrayList<ComponentName> components;
15092        ArrayList<String> strings;
15093        ArrayList<Integer> objects;
15094        boolean all;
15095
15096        ItemMatcher() {
15097            all = true;
15098        }
15099
15100        void build(String name) {
15101            ComponentName componentName = ComponentName.unflattenFromString(name);
15102            if (componentName != null) {
15103                if (components == null) {
15104                    components = new ArrayList<ComponentName>();
15105                }
15106                components.add(componentName);
15107                all = false;
15108            } else {
15109                int objectId = 0;
15110                // Not a '/' separated full component name; maybe an object ID?
15111                try {
15112                    objectId = Integer.parseInt(name, 16);
15113                    if (objects == null) {
15114                        objects = new ArrayList<Integer>();
15115                    }
15116                    objects.add(objectId);
15117                    all = false;
15118                } catch (RuntimeException e) {
15119                    // Not an integer; just do string match.
15120                    if (strings == null) {
15121                        strings = new ArrayList<String>();
15122                    }
15123                    strings.add(name);
15124                    all = false;
15125                }
15126            }
15127        }
15128
15129        int build(String[] args, int opti) {
15130            for (; opti<args.length; opti++) {
15131                String name = args[opti];
15132                if ("--".equals(name)) {
15133                    return opti+1;
15134                }
15135                build(name);
15136            }
15137            return opti;
15138        }
15139
15140        boolean match(Object object, ComponentName comp) {
15141            if (all) {
15142                return true;
15143            }
15144            if (components != null) {
15145                for (int i=0; i<components.size(); i++) {
15146                    if (components.get(i).equals(comp)) {
15147                        return true;
15148                    }
15149                }
15150            }
15151            if (objects != null) {
15152                for (int i=0; i<objects.size(); i++) {
15153                    if (System.identityHashCode(object) == objects.get(i)) {
15154                        return true;
15155                    }
15156                }
15157            }
15158            if (strings != null) {
15159                String flat = comp.flattenToString();
15160                for (int i=0; i<strings.size(); i++) {
15161                    if (flat.contains(strings.get(i))) {
15162                        return true;
15163                    }
15164                }
15165            }
15166            return false;
15167        }
15168    }
15169
15170    /**
15171     * There are three things that cmd can be:
15172     *  - a flattened component name that matches an existing activity
15173     *  - the cmd arg isn't the flattened component name of an existing activity:
15174     *    dump all activity whose component contains the cmd as a substring
15175     *  - A hex number of the ActivityRecord object instance.
15176     */
15177    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15178            int opti, boolean dumpAll) {
15179        ArrayList<ActivityRecord> activities;
15180
15181        synchronized (this) {
15182            activities = mStackSupervisor.getDumpActivitiesLocked(name);
15183        }
15184
15185        if (activities.size() <= 0) {
15186            return false;
15187        }
15188
15189        String[] newArgs = new String[args.length - opti];
15190        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15191
15192        TaskRecord lastTask = null;
15193        boolean needSep = false;
15194        for (int i=activities.size()-1; i>=0; i--) {
15195            ActivityRecord r = activities.get(i);
15196            if (needSep) {
15197                pw.println();
15198            }
15199            needSep = true;
15200            synchronized (this) {
15201                if (lastTask != r.task) {
15202                    lastTask = r.task;
15203                    pw.print("TASK "); pw.print(lastTask.affinity);
15204                            pw.print(" id="); pw.println(lastTask.taskId);
15205                    if (dumpAll) {
15206                        lastTask.dump(pw, "  ");
15207                    }
15208                }
15209            }
15210            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
15211        }
15212        return true;
15213    }
15214
15215    /**
15216     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
15217     * there is a thread associated with the activity.
15218     */
15219    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
15220            final ActivityRecord r, String[] args, boolean dumpAll) {
15221        String innerPrefix = prefix + "  ";
15222        synchronized (this) {
15223            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
15224                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
15225                    pw.print(" pid=");
15226                    if (r.app != null) pw.println(r.app.pid);
15227                    else pw.println("(not running)");
15228            if (dumpAll) {
15229                r.dump(pw, innerPrefix);
15230            }
15231        }
15232        if (r.app != null && r.app.thread != null) {
15233            // flush anything that is already in the PrintWriter since the thread is going
15234            // to write to the file descriptor directly
15235            pw.flush();
15236            try {
15237                TransferPipe tp = new TransferPipe();
15238                try {
15239                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
15240                            r.appToken, innerPrefix, args);
15241                    tp.go(fd);
15242                } finally {
15243                    tp.kill();
15244                }
15245            } catch (IOException e) {
15246                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
15247            } catch (RemoteException e) {
15248                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
15249            }
15250        }
15251    }
15252
15253    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15254            int opti, boolean dumpAll, String dumpPackage) {
15255        boolean needSep = false;
15256        boolean onlyHistory = false;
15257        boolean printedAnything = false;
15258
15259        if ("history".equals(dumpPackage)) {
15260            if (opti < args.length && "-s".equals(args[opti])) {
15261                dumpAll = false;
15262            }
15263            onlyHistory = true;
15264            dumpPackage = null;
15265        }
15266
15267        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
15268        if (!onlyHistory && dumpAll) {
15269            if (mRegisteredReceivers.size() > 0) {
15270                boolean printed = false;
15271                Iterator it = mRegisteredReceivers.values().iterator();
15272                while (it.hasNext()) {
15273                    ReceiverList r = (ReceiverList)it.next();
15274                    if (dumpPackage != null && (r.app == null ||
15275                            !dumpPackage.equals(r.app.info.packageName))) {
15276                        continue;
15277                    }
15278                    if (!printed) {
15279                        pw.println("  Registered Receivers:");
15280                        needSep = true;
15281                        printed = true;
15282                        printedAnything = true;
15283                    }
15284                    pw.print("  * "); pw.println(r);
15285                    r.dump(pw, "    ");
15286                }
15287            }
15288
15289            if (mReceiverResolver.dump(pw, needSep ?
15290                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
15291                    "    ", dumpPackage, false, false)) {
15292                needSep = true;
15293                printedAnything = true;
15294            }
15295        }
15296
15297        for (BroadcastQueue q : mBroadcastQueues) {
15298            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
15299            printedAnything |= needSep;
15300        }
15301
15302        needSep = true;
15303
15304        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
15305            for (int user=0; user<mStickyBroadcasts.size(); user++) {
15306                if (needSep) {
15307                    pw.println();
15308                }
15309                needSep = true;
15310                printedAnything = true;
15311                pw.print("  Sticky broadcasts for user ");
15312                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
15313                StringBuilder sb = new StringBuilder(128);
15314                for (Map.Entry<String, ArrayList<Intent>> ent
15315                        : mStickyBroadcasts.valueAt(user).entrySet()) {
15316                    pw.print("  * Sticky action "); pw.print(ent.getKey());
15317                    if (dumpAll) {
15318                        pw.println(":");
15319                        ArrayList<Intent> intents = ent.getValue();
15320                        final int N = intents.size();
15321                        for (int i=0; i<N; i++) {
15322                            sb.setLength(0);
15323                            sb.append("    Intent: ");
15324                            intents.get(i).toShortString(sb, false, true, false, false);
15325                            pw.println(sb.toString());
15326                            Bundle bundle = intents.get(i).getExtras();
15327                            if (bundle != null) {
15328                                pw.print("      ");
15329                                pw.println(bundle.toString());
15330                            }
15331                        }
15332                    } else {
15333                        pw.println("");
15334                    }
15335                }
15336            }
15337        }
15338
15339        if (!onlyHistory && dumpAll) {
15340            pw.println();
15341            for (BroadcastQueue queue : mBroadcastQueues) {
15342                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
15343                        + queue.mBroadcastsScheduled);
15344            }
15345            pw.println("  mHandler:");
15346            mHandler.dump(new PrintWriterPrinter(pw), "    ");
15347            needSep = true;
15348            printedAnything = true;
15349        }
15350
15351        if (!printedAnything) {
15352            pw.println("  (nothing)");
15353        }
15354    }
15355
15356    void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15357            int opti, boolean dumpAll, String dumpPackage) {
15358        if (mCurBroadcastStats == null) {
15359            return;
15360        }
15361
15362        pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
15363        final long now = SystemClock.elapsedRealtime();
15364        if (mLastBroadcastStats != null) {
15365            pw.print("  Last stats (from ");
15366            TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
15367            pw.print(" to ");
15368            TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
15369            pw.print(", ");
15370            TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
15371                    - mLastBroadcastStats.mStartUptime, pw);
15372            pw.println(" uptime):");
15373            if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15374                pw.println("    (nothing)");
15375            }
15376            pw.println();
15377        }
15378        pw.print("  Current stats (from ");
15379        TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
15380        pw.print(" to now, ");
15381        TimeUtils.formatDuration(SystemClock.uptimeMillis()
15382                - mCurBroadcastStats.mStartUptime, pw);
15383        pw.println(" uptime):");
15384        if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15385            pw.println("    (nothing)");
15386        }
15387    }
15388
15389    void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15390            int opti, boolean fullCheckin, String dumpPackage) {
15391        if (mCurBroadcastStats == null) {
15392            return;
15393        }
15394
15395        if (mLastBroadcastStats != null) {
15396            mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15397            if (fullCheckin) {
15398                mLastBroadcastStats = null;
15399                return;
15400            }
15401        }
15402        mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15403        if (fullCheckin) {
15404            mCurBroadcastStats = null;
15405        }
15406    }
15407
15408    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15409            int opti, boolean dumpAll, String dumpPackage) {
15410        boolean needSep;
15411        boolean printedAnything = false;
15412
15413        ItemMatcher matcher = new ItemMatcher();
15414        matcher.build(args, opti);
15415
15416        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
15417
15418        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
15419        printedAnything |= needSep;
15420
15421        if (mLaunchingProviders.size() > 0) {
15422            boolean printed = false;
15423            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
15424                ContentProviderRecord r = mLaunchingProviders.get(i);
15425                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
15426                    continue;
15427                }
15428                if (!printed) {
15429                    if (needSep) pw.println();
15430                    needSep = true;
15431                    pw.println("  Launching content providers:");
15432                    printed = true;
15433                    printedAnything = true;
15434                }
15435                pw.print("  Launching #"); pw.print(i); pw.print(": ");
15436                        pw.println(r);
15437            }
15438        }
15439
15440        if (!printedAnything) {
15441            pw.println("  (nothing)");
15442        }
15443    }
15444
15445    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15446            int opti, boolean dumpAll, String dumpPackage) {
15447        boolean needSep = false;
15448        boolean printedAnything = false;
15449
15450        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
15451
15452        if (mGrantedUriPermissions.size() > 0) {
15453            boolean printed = false;
15454            int dumpUid = -2;
15455            if (dumpPackage != null) {
15456                try {
15457                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
15458                            MATCH_UNINSTALLED_PACKAGES, 0);
15459                } catch (NameNotFoundException e) {
15460                    dumpUid = -1;
15461                }
15462            }
15463            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
15464                int uid = mGrantedUriPermissions.keyAt(i);
15465                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
15466                    continue;
15467                }
15468                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
15469                if (!printed) {
15470                    if (needSep) pw.println();
15471                    needSep = true;
15472                    pw.println("  Granted Uri Permissions:");
15473                    printed = true;
15474                    printedAnything = true;
15475                }
15476                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
15477                for (UriPermission perm : perms.values()) {
15478                    pw.print("    "); pw.println(perm);
15479                    if (dumpAll) {
15480                        perm.dump(pw, "      ");
15481                    }
15482                }
15483            }
15484        }
15485
15486        if (!printedAnything) {
15487            pw.println("  (nothing)");
15488        }
15489    }
15490
15491    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15492            int opti, boolean dumpAll, String dumpPackage) {
15493        boolean printed = false;
15494
15495        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
15496
15497        if (mIntentSenderRecords.size() > 0) {
15498            Iterator<WeakReference<PendingIntentRecord>> it
15499                    = mIntentSenderRecords.values().iterator();
15500            while (it.hasNext()) {
15501                WeakReference<PendingIntentRecord> ref = it.next();
15502                PendingIntentRecord rec = ref != null ? ref.get(): null;
15503                if (dumpPackage != null && (rec == null
15504                        || !dumpPackage.equals(rec.key.packageName))) {
15505                    continue;
15506                }
15507                printed = true;
15508                if (rec != null) {
15509                    pw.print("  * "); pw.println(rec);
15510                    if (dumpAll) {
15511                        rec.dump(pw, "    ");
15512                    }
15513                } else {
15514                    pw.print("  * "); pw.println(ref);
15515                }
15516            }
15517        }
15518
15519        if (!printed) {
15520            pw.println("  (nothing)");
15521        }
15522    }
15523
15524    private static final int dumpProcessList(PrintWriter pw,
15525            ActivityManagerService service, List list,
15526            String prefix, String normalLabel, String persistentLabel,
15527            String dumpPackage) {
15528        int numPers = 0;
15529        final int N = list.size()-1;
15530        for (int i=N; i>=0; i--) {
15531            ProcessRecord r = (ProcessRecord)list.get(i);
15532            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15533                continue;
15534            }
15535            pw.println(String.format("%s%s #%2d: %s",
15536                    prefix, (r.persistent ? persistentLabel : normalLabel),
15537                    i, r.toString()));
15538            if (r.persistent) {
15539                numPers++;
15540            }
15541        }
15542        return numPers;
15543    }
15544
15545    private static final boolean dumpProcessOomList(PrintWriter pw,
15546            ActivityManagerService service, List<ProcessRecord> origList,
15547            String prefix, String normalLabel, String persistentLabel,
15548            boolean inclDetails, String dumpPackage) {
15549
15550        ArrayList<Pair<ProcessRecord, Integer>> list
15551                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15552        for (int i=0; i<origList.size(); i++) {
15553            ProcessRecord r = origList.get(i);
15554            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15555                continue;
15556            }
15557            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15558        }
15559
15560        if (list.size() <= 0) {
15561            return false;
15562        }
15563
15564        Comparator<Pair<ProcessRecord, Integer>> comparator
15565                = new Comparator<Pair<ProcessRecord, Integer>>() {
15566            @Override
15567            public int compare(Pair<ProcessRecord, Integer> object1,
15568                    Pair<ProcessRecord, Integer> object2) {
15569                if (object1.first.setAdj != object2.first.setAdj) {
15570                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15571                }
15572                if (object1.first.setProcState != object2.first.setProcState) {
15573                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15574                }
15575                if (object1.second.intValue() != object2.second.intValue()) {
15576                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15577                }
15578                return 0;
15579            }
15580        };
15581
15582        Collections.sort(list, comparator);
15583
15584        final long curRealtime = SystemClock.elapsedRealtime();
15585        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15586        final long curUptime = SystemClock.uptimeMillis();
15587        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15588
15589        for (int i=list.size()-1; i>=0; i--) {
15590            ProcessRecord r = list.get(i).first;
15591            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15592            char schedGroup;
15593            switch (r.setSchedGroup) {
15594                case ProcessList.SCHED_GROUP_BACKGROUND:
15595                    schedGroup = 'B';
15596                    break;
15597                case ProcessList.SCHED_GROUP_DEFAULT:
15598                    schedGroup = 'F';
15599                    break;
15600                case ProcessList.SCHED_GROUP_TOP_APP:
15601                    schedGroup = 'T';
15602                    break;
15603                default:
15604                    schedGroup = '?';
15605                    break;
15606            }
15607            char foreground;
15608            if (r.foregroundActivities) {
15609                foreground = 'A';
15610            } else if (r.foregroundServices) {
15611                foreground = 'S';
15612            } else {
15613                foreground = ' ';
15614            }
15615            String procState = ProcessList.makeProcStateString(r.curProcState);
15616            pw.print(prefix);
15617            pw.print(r.persistent ? persistentLabel : normalLabel);
15618            pw.print(" #");
15619            int num = (origList.size()-1)-list.get(i).second;
15620            if (num < 10) pw.print(' ');
15621            pw.print(num);
15622            pw.print(": ");
15623            pw.print(oomAdj);
15624            pw.print(' ');
15625            pw.print(schedGroup);
15626            pw.print('/');
15627            pw.print(foreground);
15628            pw.print('/');
15629            pw.print(procState);
15630            pw.print(" trm:");
15631            if (r.trimMemoryLevel < 10) pw.print(' ');
15632            pw.print(r.trimMemoryLevel);
15633            pw.print(' ');
15634            pw.print(r.toShortString());
15635            pw.print(" (");
15636            pw.print(r.adjType);
15637            pw.println(')');
15638            if (r.adjSource != null || r.adjTarget != null) {
15639                pw.print(prefix);
15640                pw.print("    ");
15641                if (r.adjTarget instanceof ComponentName) {
15642                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15643                } else if (r.adjTarget != null) {
15644                    pw.print(r.adjTarget.toString());
15645                } else {
15646                    pw.print("{null}");
15647                }
15648                pw.print("<=");
15649                if (r.adjSource instanceof ProcessRecord) {
15650                    pw.print("Proc{");
15651                    pw.print(((ProcessRecord)r.adjSource).toShortString());
15652                    pw.println("}");
15653                } else if (r.adjSource != null) {
15654                    pw.println(r.adjSource.toString());
15655                } else {
15656                    pw.println("{null}");
15657                }
15658            }
15659            if (inclDetails) {
15660                pw.print(prefix);
15661                pw.print("    ");
15662                pw.print("oom: max="); pw.print(r.maxAdj);
15663                pw.print(" curRaw="); pw.print(r.curRawAdj);
15664                pw.print(" setRaw="); pw.print(r.setRawAdj);
15665                pw.print(" cur="); pw.print(r.curAdj);
15666                pw.print(" set="); pw.println(r.setAdj);
15667                pw.print(prefix);
15668                pw.print("    ");
15669                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15670                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15671                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15672                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15673                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15674                pw.println();
15675                pw.print(prefix);
15676                pw.print("    ");
15677                pw.print("cached="); pw.print(r.cached);
15678                pw.print(" empty="); pw.print(r.empty);
15679                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15680
15681                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15682                    if (r.lastWakeTime != 0) {
15683                        long wtime;
15684                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15685                        synchronized (stats) {
15686                            wtime = stats.getProcessWakeTime(r.info.uid,
15687                                    r.pid, curRealtime);
15688                        }
15689                        long timeUsed = wtime - r.lastWakeTime;
15690                        pw.print(prefix);
15691                        pw.print("    ");
15692                        pw.print("keep awake over ");
15693                        TimeUtils.formatDuration(realtimeSince, pw);
15694                        pw.print(" used ");
15695                        TimeUtils.formatDuration(timeUsed, pw);
15696                        pw.print(" (");
15697                        pw.print((timeUsed*100)/realtimeSince);
15698                        pw.println("%)");
15699                    }
15700                    if (r.lastCpuTime != 0) {
15701                        long timeUsed = r.curCpuTime - r.lastCpuTime;
15702                        pw.print(prefix);
15703                        pw.print("    ");
15704                        pw.print("run cpu over ");
15705                        TimeUtils.formatDuration(uptimeSince, pw);
15706                        pw.print(" used ");
15707                        TimeUtils.formatDuration(timeUsed, pw);
15708                        pw.print(" (");
15709                        pw.print((timeUsed*100)/uptimeSince);
15710                        pw.println("%)");
15711                    }
15712                }
15713            }
15714        }
15715        return true;
15716    }
15717
15718    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15719            String[] args) {
15720        ArrayList<ProcessRecord> procs;
15721        synchronized (this) {
15722            if (args != null && args.length > start
15723                    && args[start].charAt(0) != '-') {
15724                procs = new ArrayList<ProcessRecord>();
15725                int pid = -1;
15726                try {
15727                    pid = Integer.parseInt(args[start]);
15728                } catch (NumberFormatException e) {
15729                }
15730                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15731                    ProcessRecord proc = mLruProcesses.get(i);
15732                    if (proc.pid == pid) {
15733                        procs.add(proc);
15734                    } else if (allPkgs && proc.pkgList != null
15735                            && proc.pkgList.containsKey(args[start])) {
15736                        procs.add(proc);
15737                    } else if (proc.processName.equals(args[start])) {
15738                        procs.add(proc);
15739                    }
15740                }
15741                if (procs.size() <= 0) {
15742                    return null;
15743                }
15744            } else {
15745                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15746            }
15747        }
15748        return procs;
15749    }
15750
15751    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15752            PrintWriter pw, String[] args) {
15753        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15754        if (procs == null) {
15755            pw.println("No process found for: " + args[0]);
15756            return;
15757        }
15758
15759        long uptime = SystemClock.uptimeMillis();
15760        long realtime = SystemClock.elapsedRealtime();
15761        pw.println("Applications Graphics Acceleration Info:");
15762        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15763
15764        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15765            ProcessRecord r = procs.get(i);
15766            if (r.thread != null) {
15767                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15768                pw.flush();
15769                try {
15770                    TransferPipe tp = new TransferPipe();
15771                    try {
15772                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15773                        tp.go(fd);
15774                    } finally {
15775                        tp.kill();
15776                    }
15777                } catch (IOException e) {
15778                    pw.println("Failure while dumping the app: " + r);
15779                    pw.flush();
15780                } catch (RemoteException e) {
15781                    pw.println("Got a RemoteException while dumping the app " + r);
15782                    pw.flush();
15783                }
15784            }
15785        }
15786    }
15787
15788    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15789        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15790        if (procs == null) {
15791            pw.println("No process found for: " + args[0]);
15792            return;
15793        }
15794
15795        pw.println("Applications Database Info:");
15796
15797        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15798            ProcessRecord r = procs.get(i);
15799            if (r.thread != null) {
15800                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15801                pw.flush();
15802                try {
15803                    TransferPipe tp = new TransferPipe();
15804                    try {
15805                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15806                        tp.go(fd);
15807                    } finally {
15808                        tp.kill();
15809                    }
15810                } catch (IOException e) {
15811                    pw.println("Failure while dumping the app: " + r);
15812                    pw.flush();
15813                } catch (RemoteException e) {
15814                    pw.println("Got a RemoteException while dumping the app " + r);
15815                    pw.flush();
15816                }
15817            }
15818        }
15819    }
15820
15821    final static class MemItem {
15822        final boolean isProc;
15823        final String label;
15824        final String shortLabel;
15825        final long pss;
15826        final long swapPss;
15827        final int id;
15828        final boolean hasActivities;
15829        ArrayList<MemItem> subitems;
15830
15831        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15832                boolean _hasActivities) {
15833            isProc = true;
15834            label = _label;
15835            shortLabel = _shortLabel;
15836            pss = _pss;
15837            swapPss = _swapPss;
15838            id = _id;
15839            hasActivities = _hasActivities;
15840        }
15841
15842        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15843            isProc = false;
15844            label = _label;
15845            shortLabel = _shortLabel;
15846            pss = _pss;
15847            swapPss = _swapPss;
15848            id = _id;
15849            hasActivities = false;
15850        }
15851    }
15852
15853    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15854            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15855        if (sort && !isCompact) {
15856            Collections.sort(items, new Comparator<MemItem>() {
15857                @Override
15858                public int compare(MemItem lhs, MemItem rhs) {
15859                    if (lhs.pss < rhs.pss) {
15860                        return 1;
15861                    } else if (lhs.pss > rhs.pss) {
15862                        return -1;
15863                    }
15864                    return 0;
15865                }
15866            });
15867        }
15868
15869        for (int i=0; i<items.size(); i++) {
15870            MemItem mi = items.get(i);
15871            if (!isCompact) {
15872                if (dumpSwapPss) {
15873                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15874                            mi.label, stringifyKBSize(mi.swapPss));
15875                } else {
15876                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15877                }
15878            } else if (mi.isProc) {
15879                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15880                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15881                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15882                pw.println(mi.hasActivities ? ",a" : ",e");
15883            } else {
15884                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15885                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15886            }
15887            if (mi.subitems != null) {
15888                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15889                        true, isCompact, dumpSwapPss);
15890            }
15891        }
15892    }
15893
15894    // These are in KB.
15895    static final long[] DUMP_MEM_BUCKETS = new long[] {
15896        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15897        120*1024, 160*1024, 200*1024,
15898        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15899        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15900    };
15901
15902    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15903            boolean stackLike) {
15904        int start = label.lastIndexOf('.');
15905        if (start >= 0) start++;
15906        else start = 0;
15907        int end = label.length();
15908        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15909            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15910                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15911                out.append(bucket);
15912                out.append(stackLike ? "MB." : "MB ");
15913                out.append(label, start, end);
15914                return;
15915            }
15916        }
15917        out.append(memKB/1024);
15918        out.append(stackLike ? "MB." : "MB ");
15919        out.append(label, start, end);
15920    }
15921
15922    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15923            ProcessList.NATIVE_ADJ,
15924            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15925            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15926            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15927            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15928            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15929            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
15930    };
15931    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15932            "Native",
15933            "System", "Persistent", "Persistent Service", "Foreground",
15934            "Visible", "Perceptible",
15935            "Heavy Weight", "Backup",
15936            "A Services", "Home",
15937            "Previous", "B Services", "Cached"
15938    };
15939    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15940            "native",
15941            "sys", "pers", "persvc", "fore",
15942            "vis", "percept",
15943            "heavy", "backup",
15944            "servicea", "home",
15945            "prev", "serviceb", "cached"
15946    };
15947
15948    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15949            long realtime, boolean isCheckinRequest, boolean isCompact) {
15950        if (isCompact) {
15951            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15952        }
15953        if (isCheckinRequest || isCompact) {
15954            // short checkin version
15955            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15956        } else {
15957            pw.println("Applications Memory Usage (in Kilobytes):");
15958            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15959        }
15960    }
15961
15962    private static final int KSM_SHARED = 0;
15963    private static final int KSM_SHARING = 1;
15964    private static final int KSM_UNSHARED = 2;
15965    private static final int KSM_VOLATILE = 3;
15966
15967    private final long[] getKsmInfo() {
15968        long[] longOut = new long[4];
15969        final int[] SINGLE_LONG_FORMAT = new int[] {
15970            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15971        };
15972        long[] longTmp = new long[1];
15973        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15974                SINGLE_LONG_FORMAT, null, longTmp, null);
15975        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15976        longTmp[0] = 0;
15977        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15978                SINGLE_LONG_FORMAT, null, longTmp, null);
15979        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15980        longTmp[0] = 0;
15981        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15982                SINGLE_LONG_FORMAT, null, longTmp, null);
15983        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15984        longTmp[0] = 0;
15985        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15986                SINGLE_LONG_FORMAT, null, longTmp, null);
15987        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15988        return longOut;
15989    }
15990
15991    private static String stringifySize(long size, int order) {
15992        Locale locale = Locale.US;
15993        switch (order) {
15994            case 1:
15995                return String.format(locale, "%,13d", size);
15996            case 1024:
15997                return String.format(locale, "%,9dK", size / 1024);
15998            case 1024 * 1024:
15999                return String.format(locale, "%,5dM", size / 1024 / 1024);
16000            case 1024 * 1024 * 1024:
16001                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
16002            default:
16003                throw new IllegalArgumentException("Invalid size order");
16004        }
16005    }
16006
16007    private static String stringifyKBSize(long size) {
16008        return stringifySize(size * 1024, 1024);
16009    }
16010
16011    // Update this version number in case you change the 'compact' format
16012    private static final int MEMINFO_COMPACT_VERSION = 1;
16013
16014    final void dumpApplicationMemoryUsage(FileDescriptor fd,
16015            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
16016        boolean dumpDetails = false;
16017        boolean dumpFullDetails = false;
16018        boolean dumpDalvik = false;
16019        boolean dumpSummaryOnly = false;
16020        boolean dumpUnreachable = false;
16021        boolean oomOnly = false;
16022        boolean isCompact = false;
16023        boolean localOnly = false;
16024        boolean packages = false;
16025        boolean isCheckinRequest = false;
16026        boolean dumpSwapPss = false;
16027
16028        int opti = 0;
16029        while (opti < args.length) {
16030            String opt = args[opti];
16031            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
16032                break;
16033            }
16034            opti++;
16035            if ("-a".equals(opt)) {
16036                dumpDetails = true;
16037                dumpFullDetails = true;
16038                dumpDalvik = true;
16039                dumpSwapPss = true;
16040            } else if ("-d".equals(opt)) {
16041                dumpDalvik = true;
16042            } else if ("-c".equals(opt)) {
16043                isCompact = true;
16044            } else if ("-s".equals(opt)) {
16045                dumpDetails = true;
16046                dumpSummaryOnly = true;
16047            } else if ("-S".equals(opt)) {
16048                dumpSwapPss = true;
16049            } else if ("--unreachable".equals(opt)) {
16050                dumpUnreachable = true;
16051            } else if ("--oom".equals(opt)) {
16052                oomOnly = true;
16053            } else if ("--local".equals(opt)) {
16054                localOnly = true;
16055            } else if ("--package".equals(opt)) {
16056                packages = true;
16057            } else if ("--checkin".equals(opt)) {
16058                isCheckinRequest = true;
16059
16060            } else if ("-h".equals(opt)) {
16061                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
16062                pw.println("  -a: include all available information for each process.");
16063                pw.println("  -d: include dalvik details.");
16064                pw.println("  -c: dump in a compact machine-parseable representation.");
16065                pw.println("  -s: dump only summary of application memory usage.");
16066                pw.println("  -S: dump also SwapPss.");
16067                pw.println("  --oom: only show processes organized by oom adj.");
16068                pw.println("  --local: only collect details locally, don't call process.");
16069                pw.println("  --package: interpret process arg as package, dumping all");
16070                pw.println("             processes that have loaded that package.");
16071                pw.println("  --checkin: dump data for a checkin");
16072                pw.println("If [process] is specified it can be the name or ");
16073                pw.println("pid of a specific process to dump.");
16074                return;
16075            } else {
16076                pw.println("Unknown argument: " + opt + "; use -h for help");
16077            }
16078        }
16079
16080        long uptime = SystemClock.uptimeMillis();
16081        long realtime = SystemClock.elapsedRealtime();
16082        final long[] tmpLong = new long[1];
16083
16084        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
16085        if (procs == null) {
16086            // No Java processes.  Maybe they want to print a native process.
16087            if (args != null && args.length > opti
16088                    && args[opti].charAt(0) != '-') {
16089                ArrayList<ProcessCpuTracker.Stats> nativeProcs
16090                        = new ArrayList<ProcessCpuTracker.Stats>();
16091                updateCpuStatsNow();
16092                int findPid = -1;
16093                try {
16094                    findPid = Integer.parseInt(args[opti]);
16095                } catch (NumberFormatException e) {
16096                }
16097                synchronized (mProcessCpuTracker) {
16098                    final int N = mProcessCpuTracker.countStats();
16099                    for (int i=0; i<N; i++) {
16100                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16101                        if (st.pid == findPid || (st.baseName != null
16102                                && st.baseName.equals(args[opti]))) {
16103                            nativeProcs.add(st);
16104                        }
16105                    }
16106                }
16107                if (nativeProcs.size() > 0) {
16108                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
16109                            isCompact);
16110                    Debug.MemoryInfo mi = null;
16111                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
16112                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
16113                        final int pid = r.pid;
16114                        if (!isCheckinRequest && dumpDetails) {
16115                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
16116                        }
16117                        if (mi == null) {
16118                            mi = new Debug.MemoryInfo();
16119                        }
16120                        if (dumpDetails || (!brief && !oomOnly)) {
16121                            Debug.getMemoryInfo(pid, mi);
16122                        } else {
16123                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16124                            mi.dalvikPrivateDirty = (int)tmpLong[0];
16125                        }
16126                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16127                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
16128                        if (isCheckinRequest) {
16129                            pw.println();
16130                        }
16131                    }
16132                    return;
16133                }
16134            }
16135            pw.println("No process found for: " + args[opti]);
16136            return;
16137        }
16138
16139        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
16140            dumpDetails = true;
16141        }
16142
16143        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
16144
16145        String[] innerArgs = new String[args.length-opti];
16146        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
16147
16148        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
16149        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
16150        long nativePss = 0;
16151        long nativeSwapPss = 0;
16152        long dalvikPss = 0;
16153        long dalvikSwapPss = 0;
16154        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16155                EmptyArray.LONG;
16156        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16157                EmptyArray.LONG;
16158        long otherPss = 0;
16159        long otherSwapPss = 0;
16160        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16161        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16162
16163        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16164        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16165        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
16166                new ArrayList[DUMP_MEM_OOM_LABEL.length];
16167
16168        long totalPss = 0;
16169        long totalSwapPss = 0;
16170        long cachedPss = 0;
16171        long cachedSwapPss = 0;
16172        boolean hasSwapPss = false;
16173
16174        Debug.MemoryInfo mi = null;
16175        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16176            final ProcessRecord r = procs.get(i);
16177            final IApplicationThread thread;
16178            final int pid;
16179            final int oomAdj;
16180            final boolean hasActivities;
16181            synchronized (this) {
16182                thread = r.thread;
16183                pid = r.pid;
16184                oomAdj = r.getSetAdjWithServices();
16185                hasActivities = r.activities.size() > 0;
16186            }
16187            if (thread != null) {
16188                if (!isCheckinRequest && dumpDetails) {
16189                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
16190                }
16191                if (mi == null) {
16192                    mi = new Debug.MemoryInfo();
16193                }
16194                if (dumpDetails || (!brief && !oomOnly)) {
16195                    Debug.getMemoryInfo(pid, mi);
16196                    hasSwapPss = mi.hasSwappedOutPss;
16197                } else {
16198                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16199                    mi.dalvikPrivateDirty = (int)tmpLong[0];
16200                }
16201                if (dumpDetails) {
16202                    if (localOnly) {
16203                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16204                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
16205                        if (isCheckinRequest) {
16206                            pw.println();
16207                        }
16208                    } else {
16209                        try {
16210                            pw.flush();
16211                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
16212                                    dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
16213                        } catch (RemoteException e) {
16214                            if (!isCheckinRequest) {
16215                                pw.println("Got RemoteException!");
16216                                pw.flush();
16217                            }
16218                        }
16219                    }
16220                }
16221
16222                final long myTotalPss = mi.getTotalPss();
16223                final long myTotalUss = mi.getTotalUss();
16224                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16225
16226                synchronized (this) {
16227                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
16228                        // Record this for posterity if the process has been stable.
16229                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
16230                    }
16231                }
16232
16233                if (!isCheckinRequest && mi != null) {
16234                    totalPss += myTotalPss;
16235                    totalSwapPss += myTotalSwapPss;
16236                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
16237                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
16238                            myTotalSwapPss, pid, hasActivities);
16239                    procMems.add(pssItem);
16240                    procMemsMap.put(pid, pssItem);
16241
16242                    nativePss += mi.nativePss;
16243                    nativeSwapPss += mi.nativeSwappedOutPss;
16244                    dalvikPss += mi.dalvikPss;
16245                    dalvikSwapPss += mi.dalvikSwappedOutPss;
16246                    for (int j=0; j<dalvikSubitemPss.length; j++) {
16247                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16248                        dalvikSubitemSwapPss[j] +=
16249                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16250                    }
16251                    otherPss += mi.otherPss;
16252                    otherSwapPss += mi.otherSwappedOutPss;
16253                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16254                        long mem = mi.getOtherPss(j);
16255                        miscPss[j] += mem;
16256                        otherPss -= mem;
16257                        mem = mi.getOtherSwappedOutPss(j);
16258                        miscSwapPss[j] += mem;
16259                        otherSwapPss -= mem;
16260                    }
16261
16262                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16263                        cachedPss += myTotalPss;
16264                        cachedSwapPss += myTotalSwapPss;
16265                    }
16266
16267                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
16268                        if (oomIndex == (oomPss.length - 1)
16269                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
16270                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
16271                            oomPss[oomIndex] += myTotalPss;
16272                            oomSwapPss[oomIndex] += myTotalSwapPss;
16273                            if (oomProcs[oomIndex] == null) {
16274                                oomProcs[oomIndex] = new ArrayList<MemItem>();
16275                            }
16276                            oomProcs[oomIndex].add(pssItem);
16277                            break;
16278                        }
16279                    }
16280                }
16281            }
16282        }
16283
16284        long nativeProcTotalPss = 0;
16285
16286        if (!isCheckinRequest && procs.size() > 1 && !packages) {
16287            // If we are showing aggregations, also look for native processes to
16288            // include so that our aggregations are more accurate.
16289            updateCpuStatsNow();
16290            mi = null;
16291            synchronized (mProcessCpuTracker) {
16292                final int N = mProcessCpuTracker.countStats();
16293                for (int i=0; i<N; i++) {
16294                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16295                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
16296                        if (mi == null) {
16297                            mi = new Debug.MemoryInfo();
16298                        }
16299                        if (!brief && !oomOnly) {
16300                            Debug.getMemoryInfo(st.pid, mi);
16301                        } else {
16302                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
16303                            mi.nativePrivateDirty = (int)tmpLong[0];
16304                        }
16305
16306                        final long myTotalPss = mi.getTotalPss();
16307                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16308                        totalPss += myTotalPss;
16309                        nativeProcTotalPss += myTotalPss;
16310
16311                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
16312                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
16313                        procMems.add(pssItem);
16314
16315                        nativePss += mi.nativePss;
16316                        nativeSwapPss += mi.nativeSwappedOutPss;
16317                        dalvikPss += mi.dalvikPss;
16318                        dalvikSwapPss += mi.dalvikSwappedOutPss;
16319                        for (int j=0; j<dalvikSubitemPss.length; j++) {
16320                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16321                            dalvikSubitemSwapPss[j] +=
16322                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16323                        }
16324                        otherPss += mi.otherPss;
16325                        otherSwapPss += mi.otherSwappedOutPss;
16326                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16327                            long mem = mi.getOtherPss(j);
16328                            miscPss[j] += mem;
16329                            otherPss -= mem;
16330                            mem = mi.getOtherSwappedOutPss(j);
16331                            miscSwapPss[j] += mem;
16332                            otherSwapPss -= mem;
16333                        }
16334                        oomPss[0] += myTotalPss;
16335                        oomSwapPss[0] += myTotalSwapPss;
16336                        if (oomProcs[0] == null) {
16337                            oomProcs[0] = new ArrayList<MemItem>();
16338                        }
16339                        oomProcs[0].add(pssItem);
16340                    }
16341                }
16342            }
16343
16344            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
16345
16346            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
16347            final MemItem dalvikItem =
16348                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
16349            if (dalvikSubitemPss.length > 0) {
16350                dalvikItem.subitems = new ArrayList<MemItem>();
16351                for (int j=0; j<dalvikSubitemPss.length; j++) {
16352                    final String name = Debug.MemoryInfo.getOtherLabel(
16353                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
16354                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
16355                                    dalvikSubitemSwapPss[j], j));
16356                }
16357            }
16358            catMems.add(dalvikItem);
16359            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
16360            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16361                String label = Debug.MemoryInfo.getOtherLabel(j);
16362                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
16363            }
16364
16365            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
16366            for (int j=0; j<oomPss.length; j++) {
16367                if (oomPss[j] != 0) {
16368                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
16369                            : DUMP_MEM_OOM_LABEL[j];
16370                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
16371                            DUMP_MEM_OOM_ADJ[j]);
16372                    item.subitems = oomProcs[j];
16373                    oomMems.add(item);
16374                }
16375            }
16376
16377            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
16378            if (!brief && !oomOnly && !isCompact) {
16379                pw.println();
16380                pw.println("Total PSS by process:");
16381                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
16382                pw.println();
16383            }
16384            if (!isCompact) {
16385                pw.println("Total PSS by OOM adjustment:");
16386            }
16387            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
16388            if (!brief && !oomOnly) {
16389                PrintWriter out = categoryPw != null ? categoryPw : pw;
16390                if (!isCompact) {
16391                    out.println();
16392                    out.println("Total PSS by category:");
16393                }
16394                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
16395            }
16396            if (!isCompact) {
16397                pw.println();
16398            }
16399            MemInfoReader memInfo = new MemInfoReader();
16400            memInfo.readMemInfo();
16401            if (nativeProcTotalPss > 0) {
16402                synchronized (this) {
16403                    final long cachedKb = memInfo.getCachedSizeKb();
16404                    final long freeKb = memInfo.getFreeSizeKb();
16405                    final long zramKb = memInfo.getZramTotalSizeKb();
16406                    final long kernelKb = memInfo.getKernelUsedSizeKb();
16407                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
16408                            kernelKb*1024, nativeProcTotalPss*1024);
16409                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
16410                            nativeProcTotalPss);
16411                }
16412            }
16413            if (!brief) {
16414                if (!isCompact) {
16415                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
16416                    pw.print(" (status ");
16417                    switch (mLastMemoryLevel) {
16418                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
16419                            pw.println("normal)");
16420                            break;
16421                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
16422                            pw.println("moderate)");
16423                            break;
16424                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
16425                            pw.println("low)");
16426                            break;
16427                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16428                            pw.println("critical)");
16429                            break;
16430                        default:
16431                            pw.print(mLastMemoryLevel);
16432                            pw.println(")");
16433                            break;
16434                    }
16435                    pw.print(" Free RAM: ");
16436                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16437                            + memInfo.getFreeSizeKb()));
16438                    pw.print(" (");
16439                    pw.print(stringifyKBSize(cachedPss));
16440                    pw.print(" cached pss + ");
16441                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
16442                    pw.print(" cached kernel + ");
16443                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
16444                    pw.println(" free)");
16445                } else {
16446                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
16447                    pw.print(cachedPss + memInfo.getCachedSizeKb()
16448                            + memInfo.getFreeSizeKb()); pw.print(",");
16449                    pw.println(totalPss - cachedPss);
16450                }
16451            }
16452            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
16453                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16454                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
16455            if (!isCompact) {
16456                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
16457                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
16458                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
16459                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
16460                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
16461            } else {
16462                pw.print("lostram,"); pw.println(lostRAM);
16463            }
16464            if (!brief) {
16465                if (memInfo.getZramTotalSizeKb() != 0) {
16466                    if (!isCompact) {
16467                        pw.print("     ZRAM: ");
16468                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
16469                                pw.print(" physical used for ");
16470                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
16471                                        - memInfo.getSwapFreeSizeKb()));
16472                                pw.print(" in swap (");
16473                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
16474                                pw.println(" total swap)");
16475                    } else {
16476                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
16477                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
16478                                pw.println(memInfo.getSwapFreeSizeKb());
16479                    }
16480                }
16481                final long[] ksm = getKsmInfo();
16482                if (!isCompact) {
16483                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16484                            || ksm[KSM_VOLATILE] != 0) {
16485                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
16486                                pw.print(" saved from shared ");
16487                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
16488                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
16489                                pw.print(" unshared; ");
16490                                pw.print(stringifyKBSize(
16491                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
16492                    }
16493                    pw.print("   Tuning: ");
16494                    pw.print(ActivityManager.staticGetMemoryClass());
16495                    pw.print(" (large ");
16496                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16497                    pw.print("), oom ");
16498                    pw.print(stringifySize(
16499                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
16500                    pw.print(", restore limit ");
16501                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
16502                    if (ActivityManager.isLowRamDeviceStatic()) {
16503                        pw.print(" (low-ram)");
16504                    }
16505                    if (ActivityManager.isHighEndGfx()) {
16506                        pw.print(" (high-end-gfx)");
16507                    }
16508                    pw.println();
16509                } else {
16510                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16511                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16512                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16513                    pw.print("tuning,");
16514                    pw.print(ActivityManager.staticGetMemoryClass());
16515                    pw.print(',');
16516                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16517                    pw.print(',');
16518                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16519                    if (ActivityManager.isLowRamDeviceStatic()) {
16520                        pw.print(",low-ram");
16521                    }
16522                    if (ActivityManager.isHighEndGfx()) {
16523                        pw.print(",high-end-gfx");
16524                    }
16525                    pw.println();
16526                }
16527            }
16528        }
16529    }
16530
16531    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16532            long memtrack, String name) {
16533        sb.append("  ");
16534        sb.append(ProcessList.makeOomAdjString(oomAdj));
16535        sb.append(' ');
16536        sb.append(ProcessList.makeProcStateString(procState));
16537        sb.append(' ');
16538        ProcessList.appendRamKb(sb, pss);
16539        sb.append(": ");
16540        sb.append(name);
16541        if (memtrack > 0) {
16542            sb.append(" (");
16543            sb.append(stringifyKBSize(memtrack));
16544            sb.append(" memtrack)");
16545        }
16546    }
16547
16548    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16549        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16550        sb.append(" (pid ");
16551        sb.append(mi.pid);
16552        sb.append(") ");
16553        sb.append(mi.adjType);
16554        sb.append('\n');
16555        if (mi.adjReason != null) {
16556            sb.append("                      ");
16557            sb.append(mi.adjReason);
16558            sb.append('\n');
16559        }
16560    }
16561
16562    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16563        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16564        for (int i=0, N=memInfos.size(); i<N; i++) {
16565            ProcessMemInfo mi = memInfos.get(i);
16566            infoMap.put(mi.pid, mi);
16567        }
16568        updateCpuStatsNow();
16569        long[] memtrackTmp = new long[1];
16570        final List<ProcessCpuTracker.Stats> stats;
16571        // Get a list of Stats that have vsize > 0
16572        synchronized (mProcessCpuTracker) {
16573            stats = mProcessCpuTracker.getStats((st) -> {
16574                return st.vsize > 0;
16575            });
16576        }
16577        final int statsCount = stats.size();
16578        for (int i = 0; i < statsCount; i++) {
16579            ProcessCpuTracker.Stats st = stats.get(i);
16580            long pss = Debug.getPss(st.pid, null, memtrackTmp);
16581            if (pss > 0) {
16582                if (infoMap.indexOfKey(st.pid) < 0) {
16583                    ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16584                            ProcessList.NATIVE_ADJ, -1, "native", null);
16585                    mi.pss = pss;
16586                    mi.memtrack = memtrackTmp[0];
16587                    memInfos.add(mi);
16588                }
16589            }
16590        }
16591
16592        long totalPss = 0;
16593        long totalMemtrack = 0;
16594        for (int i=0, N=memInfos.size(); i<N; i++) {
16595            ProcessMemInfo mi = memInfos.get(i);
16596            if (mi.pss == 0) {
16597                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16598                mi.memtrack = memtrackTmp[0];
16599            }
16600            totalPss += mi.pss;
16601            totalMemtrack += mi.memtrack;
16602        }
16603        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16604            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16605                if (lhs.oomAdj != rhs.oomAdj) {
16606                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16607                }
16608                if (lhs.pss != rhs.pss) {
16609                    return lhs.pss < rhs.pss ? 1 : -1;
16610                }
16611                return 0;
16612            }
16613        });
16614
16615        StringBuilder tag = new StringBuilder(128);
16616        StringBuilder stack = new StringBuilder(128);
16617        tag.append("Low on memory -- ");
16618        appendMemBucket(tag, totalPss, "total", false);
16619        appendMemBucket(stack, totalPss, "total", true);
16620
16621        StringBuilder fullNativeBuilder = new StringBuilder(1024);
16622        StringBuilder shortNativeBuilder = new StringBuilder(1024);
16623        StringBuilder fullJavaBuilder = new StringBuilder(1024);
16624
16625        boolean firstLine = true;
16626        int lastOomAdj = Integer.MIN_VALUE;
16627        long extraNativeRam = 0;
16628        long extraNativeMemtrack = 0;
16629        long cachedPss = 0;
16630        for (int i=0, N=memInfos.size(); i<N; i++) {
16631            ProcessMemInfo mi = memInfos.get(i);
16632
16633            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16634                cachedPss += mi.pss;
16635            }
16636
16637            if (mi.oomAdj != ProcessList.NATIVE_ADJ
16638                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
16639                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
16640                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16641                if (lastOomAdj != mi.oomAdj) {
16642                    lastOomAdj = mi.oomAdj;
16643                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16644                        tag.append(" / ");
16645                    }
16646                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16647                        if (firstLine) {
16648                            stack.append(":");
16649                            firstLine = false;
16650                        }
16651                        stack.append("\n\t at ");
16652                    } else {
16653                        stack.append("$");
16654                    }
16655                } else {
16656                    tag.append(" ");
16657                    stack.append("$");
16658                }
16659                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16660                    appendMemBucket(tag, mi.pss, mi.name, false);
16661                }
16662                appendMemBucket(stack, mi.pss, mi.name, true);
16663                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16664                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16665                    stack.append("(");
16666                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16667                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16668                            stack.append(DUMP_MEM_OOM_LABEL[k]);
16669                            stack.append(":");
16670                            stack.append(DUMP_MEM_OOM_ADJ[k]);
16671                        }
16672                    }
16673                    stack.append(")");
16674                }
16675            }
16676
16677            appendMemInfo(fullNativeBuilder, mi);
16678            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16679                // The short form only has native processes that are >= 512K.
16680                if (mi.pss >= 512) {
16681                    appendMemInfo(shortNativeBuilder, mi);
16682                } else {
16683                    extraNativeRam += mi.pss;
16684                    extraNativeMemtrack += mi.memtrack;
16685                }
16686            } else {
16687                // Short form has all other details, but if we have collected RAM
16688                // from smaller native processes let's dump a summary of that.
16689                if (extraNativeRam > 0) {
16690                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16691                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16692                    shortNativeBuilder.append('\n');
16693                    extraNativeRam = 0;
16694                }
16695                appendMemInfo(fullJavaBuilder, mi);
16696            }
16697        }
16698
16699        fullJavaBuilder.append("           ");
16700        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16701        fullJavaBuilder.append(": TOTAL");
16702        if (totalMemtrack > 0) {
16703            fullJavaBuilder.append(" (");
16704            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16705            fullJavaBuilder.append(" memtrack)");
16706        } else {
16707        }
16708        fullJavaBuilder.append("\n");
16709
16710        MemInfoReader memInfo = new MemInfoReader();
16711        memInfo.readMemInfo();
16712        final long[] infos = memInfo.getRawInfo();
16713
16714        StringBuilder memInfoBuilder = new StringBuilder(1024);
16715        Debug.getMemInfo(infos);
16716        memInfoBuilder.append("  MemInfo: ");
16717        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16718        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16719        memInfoBuilder.append(stringifyKBSize(
16720                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16721        memInfoBuilder.append(stringifyKBSize(
16722                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16723        memInfoBuilder.append(stringifyKBSize(
16724                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16725        memInfoBuilder.append("           ");
16726        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16727        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16728        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16729        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16730        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16731            memInfoBuilder.append("  ZRAM: ");
16732            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16733            memInfoBuilder.append(" RAM, ");
16734            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16735            memInfoBuilder.append(" swap total, ");
16736            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16737            memInfoBuilder.append(" swap free\n");
16738        }
16739        final long[] ksm = getKsmInfo();
16740        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16741                || ksm[KSM_VOLATILE] != 0) {
16742            memInfoBuilder.append("  KSM: ");
16743            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16744            memInfoBuilder.append(" saved from shared ");
16745            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16746            memInfoBuilder.append("\n       ");
16747            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16748            memInfoBuilder.append(" unshared; ");
16749            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16750            memInfoBuilder.append(" volatile\n");
16751        }
16752        memInfoBuilder.append("  Free RAM: ");
16753        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16754                + memInfo.getFreeSizeKb()));
16755        memInfoBuilder.append("\n");
16756        memInfoBuilder.append("  Used RAM: ");
16757        memInfoBuilder.append(stringifyKBSize(
16758                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16759        memInfoBuilder.append("\n");
16760        memInfoBuilder.append("  Lost RAM: ");
16761        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16762                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16763                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16764        memInfoBuilder.append("\n");
16765        Slog.i(TAG, "Low on memory:");
16766        Slog.i(TAG, shortNativeBuilder.toString());
16767        Slog.i(TAG, fullJavaBuilder.toString());
16768        Slog.i(TAG, memInfoBuilder.toString());
16769
16770        StringBuilder dropBuilder = new StringBuilder(1024);
16771        /*
16772        StringWriter oomSw = new StringWriter();
16773        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16774        StringWriter catSw = new StringWriter();
16775        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16776        String[] emptyArgs = new String[] { };
16777        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16778        oomPw.flush();
16779        String oomString = oomSw.toString();
16780        */
16781        dropBuilder.append("Low on memory:");
16782        dropBuilder.append(stack);
16783        dropBuilder.append('\n');
16784        dropBuilder.append(fullNativeBuilder);
16785        dropBuilder.append(fullJavaBuilder);
16786        dropBuilder.append('\n');
16787        dropBuilder.append(memInfoBuilder);
16788        dropBuilder.append('\n');
16789        /*
16790        dropBuilder.append(oomString);
16791        dropBuilder.append('\n');
16792        */
16793        StringWriter catSw = new StringWriter();
16794        synchronized (ActivityManagerService.this) {
16795            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16796            String[] emptyArgs = new String[] { };
16797            catPw.println();
16798            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16799            catPw.println();
16800            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
16801                    false, null).dumpLocked();
16802            catPw.println();
16803            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16804            catPw.flush();
16805        }
16806        dropBuilder.append(catSw.toString());
16807        addErrorToDropBox("lowmem", null, "system_server", null,
16808                null, tag.toString(), dropBuilder.toString(), null, null);
16809        //Slog.i(TAG, "Sent to dropbox:");
16810        //Slog.i(TAG, dropBuilder.toString());
16811        synchronized (ActivityManagerService.this) {
16812            long now = SystemClock.uptimeMillis();
16813            if (mLastMemUsageReportTime < now) {
16814                mLastMemUsageReportTime = now;
16815            }
16816        }
16817    }
16818
16819    /**
16820     * Searches array of arguments for the specified string
16821     * @param args array of argument strings
16822     * @param value value to search for
16823     * @return true if the value is contained in the array
16824     */
16825    private static boolean scanArgs(String[] args, String value) {
16826        if (args != null) {
16827            for (String arg : args) {
16828                if (value.equals(arg)) {
16829                    return true;
16830                }
16831            }
16832        }
16833        return false;
16834    }
16835
16836    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16837            ContentProviderRecord cpr, boolean always) {
16838        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16839
16840        if (!inLaunching || always) {
16841            synchronized (cpr) {
16842                cpr.launchingApp = null;
16843                cpr.notifyAll();
16844            }
16845            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16846            String names[] = cpr.info.authority.split(";");
16847            for (int j = 0; j < names.length; j++) {
16848                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16849            }
16850        }
16851
16852        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16853            ContentProviderConnection conn = cpr.connections.get(i);
16854            if (conn.waiting) {
16855                // If this connection is waiting for the provider, then we don't
16856                // need to mess with its process unless we are always removing
16857                // or for some reason the provider is not currently launching.
16858                if (inLaunching && !always) {
16859                    continue;
16860                }
16861            }
16862            ProcessRecord capp = conn.client;
16863            conn.dead = true;
16864            if (conn.stableCount > 0) {
16865                if (!capp.persistent && capp.thread != null
16866                        && capp.pid != 0
16867                        && capp.pid != MY_PID) {
16868                    capp.kill("depends on provider "
16869                            + cpr.name.flattenToShortString()
16870                            + " in dying proc " + (proc != null ? proc.processName : "??")
16871                            + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
16872                }
16873            } else if (capp.thread != null && conn.provider.provider != null) {
16874                try {
16875                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16876                } catch (RemoteException e) {
16877                }
16878                // In the protocol here, we don't expect the client to correctly
16879                // clean up this connection, we'll just remove it.
16880                cpr.connections.remove(i);
16881                if (conn.client.conProviders.remove(conn)) {
16882                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16883                }
16884            }
16885        }
16886
16887        if (inLaunching && always) {
16888            mLaunchingProviders.remove(cpr);
16889        }
16890        return inLaunching;
16891    }
16892
16893    /**
16894     * Main code for cleaning up a process when it has gone away.  This is
16895     * called both as a result of the process dying, or directly when stopping
16896     * a process when running in single process mode.
16897     *
16898     * @return Returns true if the given process has been restarted, so the
16899     * app that was passed in must remain on the process lists.
16900     */
16901    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16902            boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
16903        Slog.d(TAG, "cleanUpApplicationRecord -- " + app.pid);
16904        if (index >= 0) {
16905            removeLruProcessLocked(app);
16906            ProcessList.remove(app.pid);
16907        }
16908
16909        mProcessesToGc.remove(app);
16910        mPendingPssProcesses.remove(app);
16911
16912        // Dismiss any open dialogs.
16913        if (app.crashDialog != null && !app.forceCrashReport) {
16914            app.crashDialog.dismiss();
16915            app.crashDialog = null;
16916        }
16917        if (app.anrDialog != null) {
16918            app.anrDialog.dismiss();
16919            app.anrDialog = null;
16920        }
16921        if (app.waitDialog != null) {
16922            app.waitDialog.dismiss();
16923            app.waitDialog = null;
16924        }
16925
16926        app.crashing = false;
16927        app.notResponding = false;
16928
16929        app.resetPackageList(mProcessStats);
16930        app.unlinkDeathRecipient();
16931        app.makeInactive(mProcessStats);
16932        app.waitingToKill = null;
16933        app.forcingToForeground = null;
16934        updateProcessForegroundLocked(app, false, false);
16935        app.foregroundActivities = false;
16936        app.hasShownUi = false;
16937        app.treatLikeActivity = false;
16938        app.hasAboveClient = false;
16939        app.hasClientActivities = false;
16940
16941        mServices.killServicesLocked(app, allowRestart);
16942
16943        boolean restart = false;
16944
16945        // Remove published content providers.
16946        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16947            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16948            final boolean always = app.bad || !allowRestart;
16949            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16950            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16951                // We left the provider in the launching list, need to
16952                // restart it.
16953                restart = true;
16954            }
16955
16956            cpr.provider = null;
16957            cpr.proc = null;
16958        }
16959        app.pubProviders.clear();
16960
16961        // Take care of any launching providers waiting for this process.
16962        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16963            restart = true;
16964        }
16965
16966        // Unregister from connected content providers.
16967        if (!app.conProviders.isEmpty()) {
16968            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16969                ContentProviderConnection conn = app.conProviders.get(i);
16970                conn.provider.connections.remove(conn);
16971                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16972                        conn.provider.name);
16973            }
16974            app.conProviders.clear();
16975        }
16976
16977        // At this point there may be remaining entries in mLaunchingProviders
16978        // where we were the only one waiting, so they are no longer of use.
16979        // Look for these and clean up if found.
16980        // XXX Commented out for now.  Trying to figure out a way to reproduce
16981        // the actual situation to identify what is actually going on.
16982        if (false) {
16983            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16984                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16985                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16986                    synchronized (cpr) {
16987                        cpr.launchingApp = null;
16988                        cpr.notifyAll();
16989                    }
16990                }
16991            }
16992        }
16993
16994        skipCurrentReceiverLocked(app);
16995
16996        // Unregister any receivers.
16997        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16998            removeReceiverLocked(app.receivers.valueAt(i));
16999        }
17000        app.receivers.clear();
17001
17002        // If the app is undergoing backup, tell the backup manager about it
17003        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
17004            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
17005                    + mBackupTarget.appInfo + " died during backup");
17006            mHandler.post(new Runnable() {
17007                @Override
17008                public void run(){
17009                    try {
17010                        IBackupManager bm = IBackupManager.Stub.asInterface(
17011                                ServiceManager.getService(Context.BACKUP_SERVICE));
17012                        bm.agentDisconnected(app.info.packageName);
17013                    } catch (RemoteException e) {
17014                        // can't happen; backup manager is local
17015                    }
17016                }
17017            });
17018        }
17019
17020        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
17021            ProcessChangeItem item = mPendingProcessChanges.get(i);
17022            if (item.pid == app.pid) {
17023                mPendingProcessChanges.remove(i);
17024                mAvailProcessChanges.add(item);
17025            }
17026        }
17027        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
17028                null).sendToTarget();
17029
17030        // If the caller is restarting this app, then leave it in its
17031        // current lists and let the caller take care of it.
17032        if (restarting) {
17033            return false;
17034        }
17035
17036        if (!app.persistent || app.isolated) {
17037            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
17038                    "Removing non-persistent process during cleanup: " + app);
17039            if (!replacingPid) {
17040                removeProcessNameLocked(app.processName, app.uid);
17041            }
17042            if (mHeavyWeightProcess == app) {
17043                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
17044                        mHeavyWeightProcess.userId, 0));
17045                mHeavyWeightProcess = null;
17046            }
17047        } else if (!app.removed) {
17048            // This app is persistent, so we need to keep its record around.
17049            // If it is not already on the pending app list, add it there
17050            // and start a new process for it.
17051            if (mPersistentStartingProcesses.indexOf(app) < 0) {
17052                mPersistentStartingProcesses.add(app);
17053                restart = true;
17054            }
17055        }
17056        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
17057                TAG_CLEANUP, "Clean-up removing on hold: " + app);
17058        mProcessesOnHold.remove(app);
17059
17060        if (app == mHomeProcess) {
17061            mHomeProcess = null;
17062        }
17063        if (app == mPreviousProcess) {
17064            mPreviousProcess = null;
17065        }
17066
17067        if (restart && !app.isolated) {
17068            // We have components that still need to be running in the
17069            // process, so re-launch it.
17070            if (index < 0) {
17071                ProcessList.remove(app.pid);
17072            }
17073            addProcessNameLocked(app);
17074            startProcessLocked(app, "restart", app.processName);
17075            return true;
17076        } else if (app.pid > 0 && app.pid != MY_PID) {
17077            // Goodbye!
17078            boolean removed;
17079            synchronized (mPidsSelfLocked) {
17080                mPidsSelfLocked.remove(app.pid);
17081                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
17082            }
17083            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
17084            if (app.isolated) {
17085                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
17086            }
17087            app.setPid(0);
17088        }
17089        return false;
17090    }
17091
17092    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
17093        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17094            ContentProviderRecord cpr = mLaunchingProviders.get(i);
17095            if (cpr.launchingApp == app) {
17096                return true;
17097            }
17098        }
17099        return false;
17100    }
17101
17102    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
17103        // Look through the content providers we are waiting to have launched,
17104        // and if any run in this process then either schedule a restart of
17105        // the process or kill the client waiting for it if this process has
17106        // gone bad.
17107        boolean restart = false;
17108        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17109            ContentProviderRecord cpr = mLaunchingProviders.get(i);
17110            if (cpr.launchingApp == app) {
17111                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
17112                    restart = true;
17113                } else {
17114                    removeDyingProviderLocked(app, cpr, true);
17115                }
17116            }
17117        }
17118        return restart;
17119    }
17120
17121    // =========================================================
17122    // SERVICES
17123    // =========================================================
17124
17125    @Override
17126    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
17127            int flags) {
17128        enforceNotIsolatedCaller("getServices");
17129        synchronized (this) {
17130            return mServices.getRunningServiceInfoLocked(maxNum, flags);
17131        }
17132    }
17133
17134    @Override
17135    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
17136        enforceNotIsolatedCaller("getRunningServiceControlPanel");
17137        synchronized (this) {
17138            return mServices.getRunningServiceControlPanelLocked(name);
17139        }
17140    }
17141
17142    @Override
17143    public ComponentName startService(IApplicationThread caller, Intent service,
17144            String resolvedType, String callingPackage, int userId)
17145            throws TransactionTooLargeException {
17146        enforceNotIsolatedCaller("startService");
17147        // Refuse possible leaked file descriptors
17148        if (service != null && service.hasFileDescriptors() == true) {
17149            throw new IllegalArgumentException("File descriptors passed in Intent");
17150        }
17151
17152        if (callingPackage == null) {
17153            throw new IllegalArgumentException("callingPackage cannot be null");
17154        }
17155
17156        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17157                "startService: " + service + " type=" + resolvedType);
17158        synchronized(this) {
17159            final int callingPid = Binder.getCallingPid();
17160            final int callingUid = Binder.getCallingUid();
17161            final long origId = Binder.clearCallingIdentity();
17162            ComponentName res = mServices.startServiceLocked(caller, service,
17163                    resolvedType, callingPid, callingUid, callingPackage, userId);
17164            Binder.restoreCallingIdentity(origId);
17165            return res;
17166        }
17167    }
17168
17169    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
17170            String callingPackage, int userId)
17171            throws TransactionTooLargeException {
17172        synchronized(this) {
17173            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17174                    "startServiceInPackage: " + service + " type=" + resolvedType);
17175            final long origId = Binder.clearCallingIdentity();
17176            ComponentName res = mServices.startServiceLocked(null, service,
17177                    resolvedType, -1, uid, callingPackage, userId);
17178            Binder.restoreCallingIdentity(origId);
17179            return res;
17180        }
17181    }
17182
17183    @Override
17184    public int stopService(IApplicationThread caller, Intent service,
17185            String resolvedType, int userId) {
17186        enforceNotIsolatedCaller("stopService");
17187        // Refuse possible leaked file descriptors
17188        if (service != null && service.hasFileDescriptors() == true) {
17189            throw new IllegalArgumentException("File descriptors passed in Intent");
17190        }
17191
17192        synchronized(this) {
17193            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
17194        }
17195    }
17196
17197    @Override
17198    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
17199        enforceNotIsolatedCaller("peekService");
17200        // Refuse possible leaked file descriptors
17201        if (service != null && service.hasFileDescriptors() == true) {
17202            throw new IllegalArgumentException("File descriptors passed in Intent");
17203        }
17204
17205        if (callingPackage == null) {
17206            throw new IllegalArgumentException("callingPackage cannot be null");
17207        }
17208
17209        synchronized(this) {
17210            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
17211        }
17212    }
17213
17214    @Override
17215    public boolean stopServiceToken(ComponentName className, IBinder token,
17216            int startId) {
17217        synchronized(this) {
17218            return mServices.stopServiceTokenLocked(className, token, startId);
17219        }
17220    }
17221
17222    @Override
17223    public void setServiceForeground(ComponentName className, IBinder token,
17224            int id, Notification notification, int flags) {
17225        synchronized(this) {
17226            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
17227        }
17228    }
17229
17230    @Override
17231    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
17232            boolean requireFull, String name, String callerPackage) {
17233        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
17234                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
17235    }
17236
17237    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
17238            String className, int flags) {
17239        boolean result = false;
17240        // For apps that don't have pre-defined UIDs, check for permission
17241        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
17242            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17243                if (ActivityManager.checkUidPermission(
17244                        INTERACT_ACROSS_USERS,
17245                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
17246                    ComponentName comp = new ComponentName(aInfo.packageName, className);
17247                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
17248                            + " requests FLAG_SINGLE_USER, but app does not hold "
17249                            + INTERACT_ACROSS_USERS;
17250                    Slog.w(TAG, msg);
17251                    throw new SecurityException(msg);
17252                }
17253                // Permission passed
17254                result = true;
17255            }
17256        } else if ("system".equals(componentProcessName)) {
17257            result = true;
17258        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17259            // Phone app and persistent apps are allowed to export singleuser providers.
17260            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
17261                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
17262        }
17263        if (DEBUG_MU) Slog.v(TAG_MU,
17264                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
17265                + Integer.toHexString(flags) + ") = " + result);
17266        return result;
17267    }
17268
17269    /**
17270     * Checks to see if the caller is in the same app as the singleton
17271     * component, or the component is in a special app. It allows special apps
17272     * to export singleton components but prevents exporting singleton
17273     * components for regular apps.
17274     */
17275    boolean isValidSingletonCall(int callingUid, int componentUid) {
17276        int componentAppId = UserHandle.getAppId(componentUid);
17277        return UserHandle.isSameApp(callingUid, componentUid)
17278                || componentAppId == Process.SYSTEM_UID
17279                || componentAppId == Process.PHONE_UID
17280                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
17281                        == PackageManager.PERMISSION_GRANTED;
17282    }
17283
17284    public int bindService(IApplicationThread caller, IBinder token, Intent service,
17285            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
17286            int userId) throws TransactionTooLargeException {
17287        enforceNotIsolatedCaller("bindService");
17288
17289        // Refuse possible leaked file descriptors
17290        if (service != null && service.hasFileDescriptors() == true) {
17291            throw new IllegalArgumentException("File descriptors passed in Intent");
17292        }
17293
17294        if (callingPackage == null) {
17295            throw new IllegalArgumentException("callingPackage cannot be null");
17296        }
17297
17298        synchronized(this) {
17299            return mServices.bindServiceLocked(caller, token, service,
17300                    resolvedType, connection, flags, callingPackage, userId);
17301        }
17302    }
17303
17304    public boolean unbindService(IServiceConnection connection) {
17305        synchronized (this) {
17306            return mServices.unbindServiceLocked(connection);
17307        }
17308    }
17309
17310    public void publishService(IBinder token, Intent intent, IBinder service) {
17311        // Refuse possible leaked file descriptors
17312        if (intent != null && intent.hasFileDescriptors() == true) {
17313            throw new IllegalArgumentException("File descriptors passed in Intent");
17314        }
17315
17316        synchronized(this) {
17317            if (!(token instanceof ServiceRecord)) {
17318                throw new IllegalArgumentException("Invalid service token");
17319            }
17320            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
17321        }
17322    }
17323
17324    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
17325        // Refuse possible leaked file descriptors
17326        if (intent != null && intent.hasFileDescriptors() == true) {
17327            throw new IllegalArgumentException("File descriptors passed in Intent");
17328        }
17329
17330        synchronized(this) {
17331            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
17332        }
17333    }
17334
17335    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
17336        synchronized(this) {
17337            if (!(token instanceof ServiceRecord)) {
17338                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
17339                throw new IllegalArgumentException("Invalid service token");
17340            }
17341            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
17342        }
17343    }
17344
17345    // =========================================================
17346    // BACKUP AND RESTORE
17347    // =========================================================
17348
17349    // Cause the target app to be launched if necessary and its backup agent
17350    // instantiated.  The backup agent will invoke backupAgentCreated() on the
17351    // activity manager to announce its creation.
17352    public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
17353        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
17354        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
17355
17356        IPackageManager pm = AppGlobals.getPackageManager();
17357        ApplicationInfo app = null;
17358        try {
17359            app = pm.getApplicationInfo(packageName, 0, userId);
17360        } catch (RemoteException e) {
17361            // can't happen; package manager is process-local
17362        }
17363        if (app == null) {
17364            Slog.w(TAG, "Unable to bind backup agent for " + packageName);
17365            return false;
17366        }
17367
17368        synchronized(this) {
17369            // !!! TODO: currently no check here that we're already bound
17370            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
17371            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17372            synchronized (stats) {
17373                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
17374            }
17375
17376            // Backup agent is now in use, its package can't be stopped.
17377            try {
17378                AppGlobals.getPackageManager().setPackageStoppedState(
17379                        app.packageName, false, UserHandle.getUserId(app.uid));
17380            } catch (RemoteException e) {
17381            } catch (IllegalArgumentException e) {
17382                Slog.w(TAG, "Failed trying to unstop package "
17383                        + app.packageName + ": " + e);
17384            }
17385
17386            BackupRecord r = new BackupRecord(ss, app, backupMode);
17387            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
17388                    ? new ComponentName(app.packageName, app.backupAgentName)
17389                    : new ComponentName("android", "FullBackupAgent");
17390            // startProcessLocked() returns existing proc's record if it's already running
17391            ProcessRecord proc = startProcessLocked(app.processName, app,
17392                    false, 0, "backup", hostingName, false, false, false);
17393            if (proc == null) {
17394                Slog.e(TAG, "Unable to start backup agent process " + r);
17395                return false;
17396            }
17397
17398            // If the app is a regular app (uid >= 10000) and not the system server or phone
17399            // process, etc, then mark it as being in full backup so that certain calls to the
17400            // process can be blocked. This is not reset to false anywhere because we kill the
17401            // process after the full backup is done and the ProcessRecord will vaporize anyway.
17402            if (UserHandle.isApp(app.uid) && backupMode == IApplicationThread.BACKUP_MODE_FULL) {
17403                proc.inFullBackup = true;
17404            }
17405            r.app = proc;
17406            mBackupTarget = r;
17407            mBackupAppName = app.packageName;
17408
17409            // Try not to kill the process during backup
17410            updateOomAdjLocked(proc);
17411
17412            // If the process is already attached, schedule the creation of the backup agent now.
17413            // If it is not yet live, this will be done when it attaches to the framework.
17414            if (proc.thread != null) {
17415                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
17416                try {
17417                    proc.thread.scheduleCreateBackupAgent(app,
17418                            compatibilityInfoForPackageLocked(app), backupMode);
17419                } catch (RemoteException e) {
17420                    // Will time out on the backup manager side
17421                }
17422            } else {
17423                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
17424            }
17425            // Invariants: at this point, the target app process exists and the application
17426            // is either already running or in the process of coming up.  mBackupTarget and
17427            // mBackupAppName describe the app, so that when it binds back to the AM we
17428            // know that it's scheduled for a backup-agent operation.
17429        }
17430
17431        return true;
17432    }
17433
17434    @Override
17435    public void clearPendingBackup() {
17436        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
17437        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
17438
17439        synchronized (this) {
17440            mBackupTarget = null;
17441            mBackupAppName = null;
17442        }
17443    }
17444
17445    // A backup agent has just come up
17446    public void backupAgentCreated(String agentPackageName, IBinder agent) {
17447        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
17448                + " = " + agent);
17449
17450        synchronized(this) {
17451            if (!agentPackageName.equals(mBackupAppName)) {
17452                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
17453                return;
17454            }
17455        }
17456
17457        long oldIdent = Binder.clearCallingIdentity();
17458        try {
17459            IBackupManager bm = IBackupManager.Stub.asInterface(
17460                    ServiceManager.getService(Context.BACKUP_SERVICE));
17461            bm.agentConnected(agentPackageName, agent);
17462        } catch (RemoteException e) {
17463            // can't happen; the backup manager service is local
17464        } catch (Exception e) {
17465            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
17466            e.printStackTrace();
17467        } finally {
17468            Binder.restoreCallingIdentity(oldIdent);
17469        }
17470    }
17471
17472    // done with this agent
17473    public void unbindBackupAgent(ApplicationInfo appInfo) {
17474        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
17475        if (appInfo == null) {
17476            Slog.w(TAG, "unbind backup agent for null app");
17477            return;
17478        }
17479
17480        synchronized(this) {
17481            try {
17482                if (mBackupAppName == null) {
17483                    Slog.w(TAG, "Unbinding backup agent with no active backup");
17484                    return;
17485                }
17486
17487                if (!mBackupAppName.equals(appInfo.packageName)) {
17488                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
17489                    return;
17490                }
17491
17492                // Not backing this app up any more; reset its OOM adjustment
17493                final ProcessRecord proc = mBackupTarget.app;
17494                updateOomAdjLocked(proc);
17495                proc.inFullBackup = false;
17496
17497                // If the app crashed during backup, 'thread' will be null here
17498                if (proc.thread != null) {
17499                    try {
17500                        proc.thread.scheduleDestroyBackupAgent(appInfo,
17501                                compatibilityInfoForPackageLocked(appInfo));
17502                    } catch (Exception e) {
17503                        Slog.e(TAG, "Exception when unbinding backup agent:");
17504                        e.printStackTrace();
17505                    }
17506                }
17507            } finally {
17508                mBackupTarget = null;
17509                mBackupAppName = null;
17510            }
17511        }
17512    }
17513    // =========================================================
17514    // BROADCASTS
17515    // =========================================================
17516
17517    boolean isPendingBroadcastProcessLocked(int pid) {
17518        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
17519                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
17520    }
17521
17522    void skipPendingBroadcastLocked(int pid) {
17523            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
17524            for (BroadcastQueue queue : mBroadcastQueues) {
17525                queue.skipPendingBroadcastLocked(pid);
17526            }
17527    }
17528
17529    // The app just attached; send any pending broadcasts that it should receive
17530    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
17531        boolean didSomething = false;
17532        for (BroadcastQueue queue : mBroadcastQueues) {
17533            didSomething |= queue.sendPendingBroadcastsLocked(app);
17534        }
17535        return didSomething;
17536    }
17537
17538    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
17539            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17540        enforceNotIsolatedCaller("registerReceiver");
17541        ArrayList<Intent> stickyIntents = null;
17542        ProcessRecord callerApp = null;
17543        int callingUid;
17544        int callingPid;
17545        synchronized(this) {
17546            if (caller != null) {
17547                callerApp = getRecordForAppLocked(caller);
17548                if (callerApp == null) {
17549                    throw new SecurityException(
17550                            "Unable to find app for caller " + caller
17551                            + " (pid=" + Binder.getCallingPid()
17552                            + ") when registering receiver " + receiver);
17553                }
17554                if (callerApp.info.uid != Process.SYSTEM_UID &&
17555                        !callerApp.pkgList.containsKey(callerPackage) &&
17556                        !"android".equals(callerPackage)) {
17557                    throw new SecurityException("Given caller package " + callerPackage
17558                            + " is not running in process " + callerApp);
17559                }
17560                callingUid = callerApp.info.uid;
17561                callingPid = callerApp.pid;
17562            } else {
17563                callerPackage = null;
17564                callingUid = Binder.getCallingUid();
17565                callingPid = Binder.getCallingPid();
17566            }
17567
17568            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17569                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17570
17571            Iterator<String> actions = filter.actionsIterator();
17572            if (actions == null) {
17573                ArrayList<String> noAction = new ArrayList<String>(1);
17574                noAction.add(null);
17575                actions = noAction.iterator();
17576            }
17577
17578            // Collect stickies of users
17579            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17580            while (actions.hasNext()) {
17581                String action = actions.next();
17582                for (int id : userIds) {
17583                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17584                    if (stickies != null) {
17585                        ArrayList<Intent> intents = stickies.get(action);
17586                        if (intents != null) {
17587                            if (stickyIntents == null) {
17588                                stickyIntents = new ArrayList<Intent>();
17589                            }
17590                            stickyIntents.addAll(intents);
17591                        }
17592                    }
17593                }
17594            }
17595        }
17596
17597        ArrayList<Intent> allSticky = null;
17598        if (stickyIntents != null) {
17599            final ContentResolver resolver = mContext.getContentResolver();
17600            // Look for any matching sticky broadcasts...
17601            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17602                Intent intent = stickyIntents.get(i);
17603                // If intent has scheme "content", it will need to acccess
17604                // provider that needs to lock mProviderMap in ActivityThread
17605                // and also it may need to wait application response, so we
17606                // cannot lock ActivityManagerService here.
17607                if (filter.match(resolver, intent, true, TAG) >= 0) {
17608                    if (allSticky == null) {
17609                        allSticky = new ArrayList<Intent>();
17610                    }
17611                    allSticky.add(intent);
17612                }
17613            }
17614        }
17615
17616        // The first sticky in the list is returned directly back to the client.
17617        Intent sticky = allSticky != null ? allSticky.get(0) : null;
17618        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17619        if (receiver == null) {
17620            return sticky;
17621        }
17622
17623        synchronized (this) {
17624            if (callerApp != null && (callerApp.thread == null
17625                    || callerApp.thread.asBinder() != caller.asBinder())) {
17626                // Original caller already died
17627                return null;
17628            }
17629            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17630            if (rl == null) {
17631                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17632                        userId, receiver);
17633                if (rl.app != null) {
17634                    rl.app.receivers.add(rl);
17635                } else {
17636                    try {
17637                        receiver.asBinder().linkToDeath(rl, 0);
17638                    } catch (RemoteException e) {
17639                        return sticky;
17640                    }
17641                    rl.linkedToDeath = true;
17642                }
17643                mRegisteredReceivers.put(receiver.asBinder(), rl);
17644            } else if (rl.uid != callingUid) {
17645                throw new IllegalArgumentException(
17646                        "Receiver requested to register for uid " + callingUid
17647                        + " was previously registered for uid " + rl.uid);
17648            } else if (rl.pid != callingPid) {
17649                throw new IllegalArgumentException(
17650                        "Receiver requested to register for pid " + callingPid
17651                        + " was previously registered for pid " + rl.pid);
17652            } else if (rl.userId != userId) {
17653                throw new IllegalArgumentException(
17654                        "Receiver requested to register for user " + userId
17655                        + " was previously registered for user " + rl.userId);
17656            }
17657            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17658                    permission, callingUid, userId);
17659            rl.add(bf);
17660            if (!bf.debugCheck()) {
17661                Slog.w(TAG, "==> For Dynamic broadcast");
17662            }
17663            mReceiverResolver.addFilter(bf);
17664
17665            // Enqueue broadcasts for all existing stickies that match
17666            // this filter.
17667            if (allSticky != null) {
17668                ArrayList receivers = new ArrayList();
17669                receivers.add(bf);
17670
17671                final int stickyCount = allSticky.size();
17672                for (int i = 0; i < stickyCount; i++) {
17673                    Intent intent = allSticky.get(i);
17674                    BroadcastQueue queue = broadcastQueueForIntent(intent);
17675                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17676                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17677                            null, 0, null, null, false, true, true, -1);
17678                    queue.enqueueParallelBroadcastLocked(r);
17679                    queue.scheduleBroadcastsLocked();
17680                }
17681            }
17682
17683            return sticky;
17684        }
17685    }
17686
17687    public void unregisterReceiver(IIntentReceiver receiver) {
17688        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17689
17690        final long origId = Binder.clearCallingIdentity();
17691        try {
17692            boolean doTrim = false;
17693
17694            synchronized(this) {
17695                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17696                if (rl != null) {
17697                    final BroadcastRecord r = rl.curBroadcast;
17698                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17699                        final boolean doNext = r.queue.finishReceiverLocked(
17700                                r, r.resultCode, r.resultData, r.resultExtras,
17701                                r.resultAbort, false);
17702                        if (doNext) {
17703                            doTrim = true;
17704                            r.queue.processNextBroadcast(false);
17705                        }
17706                    }
17707
17708                    if (rl.app != null) {
17709                        rl.app.receivers.remove(rl);
17710                    }
17711                    removeReceiverLocked(rl);
17712                    if (rl.linkedToDeath) {
17713                        rl.linkedToDeath = false;
17714                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
17715                    }
17716                }
17717            }
17718
17719            // If we actually concluded any broadcasts, we might now be able
17720            // to trim the recipients' apps from our working set
17721            if (doTrim) {
17722                trimApplications();
17723                return;
17724            }
17725
17726        } finally {
17727            Binder.restoreCallingIdentity(origId);
17728        }
17729    }
17730
17731    void removeReceiverLocked(ReceiverList rl) {
17732        mRegisteredReceivers.remove(rl.receiver.asBinder());
17733        for (int i = rl.size() - 1; i >= 0; i--) {
17734            mReceiverResolver.removeFilter(rl.get(i));
17735        }
17736    }
17737
17738    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17739        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17740            ProcessRecord r = mLruProcesses.get(i);
17741            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17742                try {
17743                    r.thread.dispatchPackageBroadcast(cmd, packages);
17744                } catch (RemoteException ex) {
17745                }
17746            }
17747        }
17748    }
17749
17750    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17751            int callingUid, int[] users) {
17752        // TODO: come back and remove this assumption to triage all broadcasts
17753        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17754
17755        List<ResolveInfo> receivers = null;
17756        try {
17757            HashSet<ComponentName> singleUserReceivers = null;
17758            boolean scannedFirstReceivers = false;
17759            for (int user : users) {
17760                // Skip users that have Shell restrictions, with exception of always permitted
17761                // Shell broadcasts
17762                if (callingUid == Process.SHELL_UID
17763                        && mUserController.hasUserRestriction(
17764                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17765                        && !isPermittedShellBroadcast(intent)) {
17766                    continue;
17767                }
17768                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17769                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17770                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17771                    // If this is not the system user, we need to check for
17772                    // any receivers that should be filtered out.
17773                    for (int i=0; i<newReceivers.size(); i++) {
17774                        ResolveInfo ri = newReceivers.get(i);
17775                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17776                            newReceivers.remove(i);
17777                            i--;
17778                        }
17779                    }
17780                }
17781                if (newReceivers != null && newReceivers.size() == 0) {
17782                    newReceivers = null;
17783                }
17784                if (receivers == null) {
17785                    receivers = newReceivers;
17786                } else if (newReceivers != null) {
17787                    // We need to concatenate the additional receivers
17788                    // found with what we have do far.  This would be easy,
17789                    // but we also need to de-dup any receivers that are
17790                    // singleUser.
17791                    if (!scannedFirstReceivers) {
17792                        // Collect any single user receivers we had already retrieved.
17793                        scannedFirstReceivers = true;
17794                        for (int i=0; i<receivers.size(); i++) {
17795                            ResolveInfo ri = receivers.get(i);
17796                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17797                                ComponentName cn = new ComponentName(
17798                                        ri.activityInfo.packageName, ri.activityInfo.name);
17799                                if (singleUserReceivers == null) {
17800                                    singleUserReceivers = new HashSet<ComponentName>();
17801                                }
17802                                singleUserReceivers.add(cn);
17803                            }
17804                        }
17805                    }
17806                    // Add the new results to the existing results, tracking
17807                    // and de-dupping single user receivers.
17808                    for (int i=0; i<newReceivers.size(); i++) {
17809                        ResolveInfo ri = newReceivers.get(i);
17810                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17811                            ComponentName cn = new ComponentName(
17812                                    ri.activityInfo.packageName, ri.activityInfo.name);
17813                            if (singleUserReceivers == null) {
17814                                singleUserReceivers = new HashSet<ComponentName>();
17815                            }
17816                            if (!singleUserReceivers.contains(cn)) {
17817                                singleUserReceivers.add(cn);
17818                                receivers.add(ri);
17819                            }
17820                        } else {
17821                            receivers.add(ri);
17822                        }
17823                    }
17824                }
17825            }
17826        } catch (RemoteException ex) {
17827            // pm is in same process, this will never happen.
17828        }
17829        return receivers;
17830    }
17831
17832    private boolean isPermittedShellBroadcast(Intent intent) {
17833        // remote bugreport should always be allowed to be taken
17834        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17835    }
17836
17837    private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
17838            String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
17839        final String action = intent.getAction();
17840        if (isProtectedBroadcast
17841                || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17842                || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17843                || Intent.ACTION_MEDIA_BUTTON.equals(action)
17844                || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17845                || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17846                || Intent.ACTION_MASTER_CLEAR.equals(action)
17847                || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17848                || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17849                || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
17850                || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
17851                || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
17852            // Broadcast is either protected, or it's a public action that
17853            // we've relaxed, so it's fine for system internals to send.
17854            return;
17855        }
17856
17857        // This broadcast may be a problem...  but there are often system components that
17858        // want to send an internal broadcast to themselves, which is annoying to have to
17859        // explicitly list each action as a protected broadcast, so we will check for that
17860        // one safe case and allow it: an explicit broadcast, only being received by something
17861        // that has protected itself.
17862        if (receivers != null && receivers.size() > 0
17863                && (intent.getPackage() != null || intent.getComponent() != null)) {
17864            boolean allProtected = true;
17865            for (int i = receivers.size()-1; i >= 0; i--) {
17866                Object target = receivers.get(i);
17867                if (target instanceof ResolveInfo) {
17868                    ResolveInfo ri = (ResolveInfo)target;
17869                    if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
17870                        allProtected = false;
17871                        break;
17872                    }
17873                } else {
17874                    BroadcastFilter bf = (BroadcastFilter)target;
17875                    if (bf.requiredPermission == null) {
17876                        allProtected = false;
17877                        break;
17878                    }
17879                }
17880            }
17881            if (allProtected) {
17882                // All safe!
17883                return;
17884            }
17885        }
17886
17887        // The vast majority of broadcasts sent from system internals
17888        // should be protected to avoid security holes, so yell loudly
17889        // to ensure we examine these cases.
17890        if (callerApp != null) {
17891            Log.wtf(TAG, "Sending non-protected broadcast " + action
17892                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
17893                    new Throwable());
17894        } else {
17895            Log.wtf(TAG, "Sending non-protected broadcast " + action
17896                            + " from system uid " + UserHandle.formatUid(callingUid)
17897                            + " pkg " + callerPackage,
17898                    new Throwable());
17899        }
17900    }
17901
17902    final int broadcastIntentLocked(ProcessRecord callerApp,
17903            String callerPackage, Intent intent, String resolvedType,
17904            IIntentReceiver resultTo, int resultCode, String resultData,
17905            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17906            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17907        intent = new Intent(intent);
17908
17909        // By default broadcasts do not go to stopped apps.
17910        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17911
17912        // If we have not finished booting, don't allow this to launch new processes.
17913        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17914            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17915        }
17916
17917        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17918                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17919                + " ordered=" + ordered + " userid=" + userId);
17920        if ((resultTo != null) && !ordered) {
17921            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17922        }
17923
17924        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17925                ALLOW_NON_FULL, "broadcast", callerPackage);
17926
17927        // Make sure that the user who is receiving this broadcast is running.
17928        // If not, we will just skip it. Make an exception for shutdown broadcasts
17929        // and upgrade steps.
17930
17931        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17932            if ((callingUid != Process.SYSTEM_UID
17933                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17934                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17935                Slog.w(TAG, "Skipping broadcast of " + intent
17936                        + ": user " + userId + " is stopped");
17937                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17938            }
17939        }
17940
17941        BroadcastOptions brOptions = null;
17942        if (bOptions != null) {
17943            brOptions = new BroadcastOptions(bOptions);
17944            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17945                // See if the caller is allowed to do this.  Note we are checking against
17946                // the actual real caller (not whoever provided the operation as say a
17947                // PendingIntent), because that who is actually supplied the arguments.
17948                if (checkComponentPermission(
17949                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17950                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17951                        != PackageManager.PERMISSION_GRANTED) {
17952                    String msg = "Permission Denial: " + intent.getAction()
17953                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17954                            + ", uid=" + callingUid + ")"
17955                            + " requires "
17956                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17957                    Slog.w(TAG, msg);
17958                    throw new SecurityException(msg);
17959                }
17960            }
17961        }
17962
17963        // Verify that protected broadcasts are only being sent by system code,
17964        // and that system code is only sending protected broadcasts.
17965        final String action = intent.getAction();
17966        final boolean isProtectedBroadcast;
17967        try {
17968            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17969        } catch (RemoteException e) {
17970            Slog.w(TAG, "Remote exception", e);
17971            return ActivityManager.BROADCAST_SUCCESS;
17972        }
17973
17974        final boolean isCallerSystem;
17975        switch (UserHandle.getAppId(callingUid)) {
17976            case Process.ROOT_UID:
17977            case Process.SYSTEM_UID:
17978            case Process.PHONE_UID:
17979            case Process.BLUETOOTH_UID:
17980            case Process.NFC_UID:
17981                isCallerSystem = true;
17982                break;
17983            default:
17984                isCallerSystem = (callerApp != null) && callerApp.persistent;
17985                break;
17986        }
17987
17988        // First line security check before anything else: stop non-system apps from
17989        // sending protected broadcasts.
17990        if (!isCallerSystem) {
17991            if (isProtectedBroadcast) {
17992                String msg = "Permission Denial: not allowed to send broadcast "
17993                        + action + " from pid="
17994                        + callingPid + ", uid=" + callingUid;
17995                Slog.w(TAG, msg);
17996                throw new SecurityException(msg);
17997
17998            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17999                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
18000                // Special case for compatibility: we don't want apps to send this,
18001                // but historically it has not been protected and apps may be using it
18002                // to poke their own app widget.  So, instead of making it protected,
18003                // just limit it to the caller.
18004                if (callerPackage == null) {
18005                    String msg = "Permission Denial: not allowed to send broadcast "
18006                            + action + " from unknown caller.";
18007                    Slog.w(TAG, msg);
18008                    throw new SecurityException(msg);
18009                } else if (intent.getComponent() != null) {
18010                    // They are good enough to send to an explicit component...  verify
18011                    // it is being sent to the calling app.
18012                    if (!intent.getComponent().getPackageName().equals(
18013                            callerPackage)) {
18014                        String msg = "Permission Denial: not allowed to send broadcast "
18015                                + action + " to "
18016                                + intent.getComponent().getPackageName() + " from "
18017                                + callerPackage;
18018                        Slog.w(TAG, msg);
18019                        throw new SecurityException(msg);
18020                    }
18021                } else {
18022                    // Limit broadcast to their own package.
18023                    intent.setPackage(callerPackage);
18024                }
18025            }
18026        }
18027
18028        if (action != null) {
18029            switch (action) {
18030                case Intent.ACTION_UID_REMOVED:
18031                case Intent.ACTION_PACKAGE_REMOVED:
18032                case Intent.ACTION_PACKAGE_CHANGED:
18033                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
18034                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
18035                case Intent.ACTION_PACKAGES_SUSPENDED:
18036                case Intent.ACTION_PACKAGES_UNSUSPENDED:
18037                    // Handle special intents: if this broadcast is from the package
18038                    // manager about a package being removed, we need to remove all of
18039                    // its activities from the history stack.
18040                    if (checkComponentPermission(
18041                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
18042                            callingPid, callingUid, -1, true)
18043                            != PackageManager.PERMISSION_GRANTED) {
18044                        String msg = "Permission Denial: " + intent.getAction()
18045                                + " broadcast from " + callerPackage + " (pid=" + callingPid
18046                                + ", uid=" + callingUid + ")"
18047                                + " requires "
18048                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
18049                        Slog.w(TAG, msg);
18050                        throw new SecurityException(msg);
18051                    }
18052                    switch (action) {
18053                        case Intent.ACTION_UID_REMOVED:
18054                            final Bundle intentExtras = intent.getExtras();
18055                            final int uid = intentExtras != null
18056                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
18057                            if (uid >= 0) {
18058                                mBatteryStatsService.removeUid(uid);
18059                                mAppOpsService.uidRemoved(uid);
18060                            }
18061                            break;
18062                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
18063                            // If resources are unavailable just force stop all those packages
18064                            // and flush the attribute cache as well.
18065                            String list[] =
18066                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18067                            if (list != null && list.length > 0) {
18068                                for (int i = 0; i < list.length; i++) {
18069                                    forceStopPackageLocked(list[i], -1, false, true, true,
18070                                            false, false, userId, "storage unmount");
18071                                }
18072                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
18073                                sendPackageBroadcastLocked(
18074                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
18075                                        userId);
18076                            }
18077                            break;
18078                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
18079                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
18080                            break;
18081                        case Intent.ACTION_PACKAGE_REMOVED:
18082                        case Intent.ACTION_PACKAGE_CHANGED:
18083                            Uri data = intent.getData();
18084                            String ssp;
18085                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
18086                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
18087                                final boolean replacing =
18088                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
18089                                final boolean killProcess =
18090                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
18091                                final boolean fullUninstall = removed && !replacing;
18092                                if (removed) {
18093                                    if (killProcess) {
18094                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
18095                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
18096                                                false, true, true, false, fullUninstall, userId,
18097                                                removed ? "pkg removed" : "pkg changed");
18098                                    }
18099                                    final int cmd = killProcess
18100                                            ? IApplicationThread.PACKAGE_REMOVED
18101                                            : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
18102                                    sendPackageBroadcastLocked(cmd,
18103                                            new String[] {ssp}, userId);
18104                                    if (fullUninstall) {
18105                                        mAppOpsService.packageRemoved(
18106                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
18107
18108                                        // Remove all permissions granted from/to this package
18109                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
18110
18111                                        removeTasksByPackageNameLocked(ssp, userId);
18112
18113                                        // Hide the "unsupported display" dialog if necessary.
18114                                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
18115                                                mUnsupportedDisplaySizeDialog.getPackageName())) {
18116                                            mUnsupportedDisplaySizeDialog.dismiss();
18117                                            mUnsupportedDisplaySizeDialog = null;
18118                                        }
18119                                        mCompatModePackages.handlePackageUninstalledLocked(ssp);
18120                                        mBatteryStatsService.notePackageUninstalled(ssp);
18121                                    }
18122                                } else {
18123                                    if (killProcess) {
18124                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
18125                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
18126                                                userId, ProcessList.INVALID_ADJ,
18127                                                false, true, true, false, "change " + ssp);
18128                                    }
18129                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
18130                                            intent.getStringArrayExtra(
18131                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
18132                                }
18133                            }
18134                            break;
18135                        case Intent.ACTION_PACKAGES_SUSPENDED:
18136                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
18137                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
18138                                    intent.getAction());
18139                            final String[] packageNames = intent.getStringArrayExtra(
18140                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
18141                            final int userHandle = intent.getIntExtra(
18142                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
18143
18144                            synchronized(ActivityManagerService.this) {
18145                                mRecentTasks.onPackagesSuspendedChanged(
18146                                        packageNames, suspended, userHandle);
18147                            }
18148                            break;
18149                    }
18150                    break;
18151                case Intent.ACTION_PACKAGE_REPLACED:
18152                {
18153                    final Uri data = intent.getData();
18154                    final String ssp;
18155                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18156                        final ApplicationInfo aInfo =
18157                                getPackageManagerInternalLocked().getApplicationInfo(
18158                                        ssp,
18159                                        userId);
18160                        if (aInfo == null) {
18161                            Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
18162                                    + " ssp=" + ssp + " data=" + data);
18163                            return ActivityManager.BROADCAST_SUCCESS;
18164                        }
18165                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
18166                        sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
18167                                new String[] {ssp}, userId);
18168                    }
18169                    break;
18170                }
18171                case Intent.ACTION_PACKAGE_ADDED:
18172                {
18173                    // Special case for adding a package: by default turn on compatibility mode.
18174                    Uri data = intent.getData();
18175                    String ssp;
18176                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18177                        final boolean replacing =
18178                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
18179                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
18180
18181                        try {
18182                            ApplicationInfo ai = AppGlobals.getPackageManager().
18183                                    getApplicationInfo(ssp, 0, 0);
18184                            mBatteryStatsService.notePackageInstalled(ssp,
18185                                    ai != null ? ai.versionCode : 0);
18186                        } catch (RemoteException e) {
18187                        }
18188                    }
18189                    break;
18190                }
18191                case Intent.ACTION_PACKAGE_DATA_CLEARED:
18192                {
18193                    Uri data = intent.getData();
18194                    String ssp;
18195                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18196                        // Hide the "unsupported display" dialog if necessary.
18197                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
18198                                mUnsupportedDisplaySizeDialog.getPackageName())) {
18199                            mUnsupportedDisplaySizeDialog.dismiss();
18200                            mUnsupportedDisplaySizeDialog = null;
18201                        }
18202                        mCompatModePackages.handlePackageDataClearedLocked(ssp);
18203                    }
18204                    break;
18205                }
18206                case Intent.ACTION_TIMEZONE_CHANGED:
18207                    // If this is the time zone changed action, queue up a message that will reset
18208                    // the timezone of all currently running processes. This message will get
18209                    // queued up before the broadcast happens.
18210                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
18211                    break;
18212                case Intent.ACTION_TIME_CHANGED:
18213                    // If the user set the time, let all running processes know.
18214                    final int is24Hour =
18215                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
18216                                    : 0;
18217                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
18218                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18219                    synchronized (stats) {
18220                        stats.noteCurrentTimeChangedLocked();
18221                    }
18222                    break;
18223                case Intent.ACTION_CLEAR_DNS_CACHE:
18224                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
18225                    break;
18226                case Proxy.PROXY_CHANGE_ACTION:
18227                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
18228                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
18229                    break;
18230                case android.hardware.Camera.ACTION_NEW_PICTURE:
18231                case android.hardware.Camera.ACTION_NEW_VIDEO:
18232                    // These broadcasts are no longer allowed by the system, since they can
18233                    // cause significant thrashing at a crictical point (using the camera).
18234                    // Apps should use JobScehduler to monitor for media provider changes.
18235                    Slog.w(TAG, action + " no longer allowed; dropping from "
18236                            + UserHandle.formatUid(callingUid));
18237                    if (resultTo != null) {
18238                        final BroadcastQueue queue = broadcastQueueForIntent(intent);
18239                        try {
18240                            queue.performReceiveLocked(callerApp, resultTo, intent,
18241                                    Activity.RESULT_CANCELED, null, null,
18242                                    false, false, userId);
18243                        } catch (RemoteException e) {
18244                            Slog.w(TAG, "Failure ["
18245                                    + queue.mQueueName + "] sending broadcast result of "
18246                                    + intent, e);
18247
18248                        }
18249                    }
18250                    // Lie; we don't want to crash the app.
18251                    return ActivityManager.BROADCAST_SUCCESS;
18252            }
18253        }
18254
18255        // Add to the sticky list if requested.
18256        if (sticky) {
18257            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
18258                    callingPid, callingUid)
18259                    != PackageManager.PERMISSION_GRANTED) {
18260                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
18261                        + callingPid + ", uid=" + callingUid
18262                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18263                Slog.w(TAG, msg);
18264                throw new SecurityException(msg);
18265            }
18266            if (requiredPermissions != null && requiredPermissions.length > 0) {
18267                Slog.w(TAG, "Can't broadcast sticky intent " + intent
18268                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
18269                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
18270            }
18271            if (intent.getComponent() != null) {
18272                throw new SecurityException(
18273                        "Sticky broadcasts can't target a specific component");
18274            }
18275            // We use userId directly here, since the "all" target is maintained
18276            // as a separate set of sticky broadcasts.
18277            if (userId != UserHandle.USER_ALL) {
18278                // But first, if this is not a broadcast to all users, then
18279                // make sure it doesn't conflict with an existing broadcast to
18280                // all users.
18281                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
18282                        UserHandle.USER_ALL);
18283                if (stickies != null) {
18284                    ArrayList<Intent> list = stickies.get(intent.getAction());
18285                    if (list != null) {
18286                        int N = list.size();
18287                        int i;
18288                        for (i=0; i<N; i++) {
18289                            if (intent.filterEquals(list.get(i))) {
18290                                throw new IllegalArgumentException(
18291                                        "Sticky broadcast " + intent + " for user "
18292                                        + userId + " conflicts with existing global broadcast");
18293                            }
18294                        }
18295                    }
18296                }
18297            }
18298            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18299            if (stickies == null) {
18300                stickies = new ArrayMap<>();
18301                mStickyBroadcasts.put(userId, stickies);
18302            }
18303            ArrayList<Intent> list = stickies.get(intent.getAction());
18304            if (list == null) {
18305                list = new ArrayList<>();
18306                stickies.put(intent.getAction(), list);
18307            }
18308            final int stickiesCount = list.size();
18309            int i;
18310            for (i = 0; i < stickiesCount; i++) {
18311                if (intent.filterEquals(list.get(i))) {
18312                    // This sticky already exists, replace it.
18313                    list.set(i, new Intent(intent));
18314                    break;
18315                }
18316            }
18317            if (i >= stickiesCount) {
18318                list.add(new Intent(intent));
18319            }
18320        }
18321
18322        int[] users;
18323        if (userId == UserHandle.USER_ALL) {
18324            // Caller wants broadcast to go to all started users.
18325            users = mUserController.getStartedUserArrayLocked();
18326        } else {
18327            // Caller wants broadcast to go to one specific user.
18328            users = new int[] {userId};
18329        }
18330
18331        // Figure out who all will receive this broadcast.
18332        List receivers = null;
18333        List<BroadcastFilter> registeredReceivers = null;
18334        // Need to resolve the intent to interested receivers...
18335        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
18336                 == 0) {
18337            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
18338        }
18339        if (intent.getComponent() == null) {
18340            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
18341                // Query one target user at a time, excluding shell-restricted users
18342                for (int i = 0; i < users.length; i++) {
18343                    if (mUserController.hasUserRestriction(
18344                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
18345                        continue;
18346                    }
18347                    List<BroadcastFilter> registeredReceiversForUser =
18348                            mReceiverResolver.queryIntent(intent,
18349                                    resolvedType, false, users[i]);
18350                    if (registeredReceivers == null) {
18351                        registeredReceivers = registeredReceiversForUser;
18352                    } else if (registeredReceiversForUser != null) {
18353                        registeredReceivers.addAll(registeredReceiversForUser);
18354                    }
18355                }
18356            } else {
18357                registeredReceivers = mReceiverResolver.queryIntent(intent,
18358                        resolvedType, false, userId);
18359            }
18360        }
18361
18362        final boolean replacePending =
18363                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
18364
18365        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
18366                + " replacePending=" + replacePending);
18367
18368        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
18369        if (!ordered && NR > 0) {
18370            // If we are not serializing this broadcast, then send the
18371            // registered receivers separately so they don't wait for the
18372            // components to be launched.
18373            if (isCallerSystem) {
18374                checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
18375                        isProtectedBroadcast, registeredReceivers);
18376            }
18377            final BroadcastQueue queue = broadcastQueueForIntent(intent);
18378            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18379                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
18380                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
18381                    resultExtras, ordered, sticky, false, userId);
18382            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
18383            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
18384            if (!replaced) {
18385                queue.enqueueParallelBroadcastLocked(r);
18386                queue.scheduleBroadcastsLocked();
18387            }
18388            registeredReceivers = null;
18389            NR = 0;
18390        }
18391
18392        // Merge into one list.
18393        int ir = 0;
18394        if (receivers != null) {
18395            // A special case for PACKAGE_ADDED: do not allow the package
18396            // being added to see this broadcast.  This prevents them from
18397            // using this as a back door to get run as soon as they are
18398            // installed.  Maybe in the future we want to have a special install
18399            // broadcast or such for apps, but we'd like to deliberately make
18400            // this decision.
18401            String skipPackages[] = null;
18402            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
18403                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
18404                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
18405                Uri data = intent.getData();
18406                if (data != null) {
18407                    String pkgName = data.getSchemeSpecificPart();
18408                    if (pkgName != null) {
18409                        skipPackages = new String[] { pkgName };
18410                    }
18411                }
18412            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
18413                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18414            }
18415            if (skipPackages != null && (skipPackages.length > 0)) {
18416                for (String skipPackage : skipPackages) {
18417                    if (skipPackage != null) {
18418                        int NT = receivers.size();
18419                        for (int it=0; it<NT; it++) {
18420                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
18421                            if (curt.activityInfo.packageName.equals(skipPackage)) {
18422                                receivers.remove(it);
18423                                it--;
18424                                NT--;
18425                            }
18426                        }
18427                    }
18428                }
18429            }
18430
18431            int NT = receivers != null ? receivers.size() : 0;
18432            int it = 0;
18433            ResolveInfo curt = null;
18434            BroadcastFilter curr = null;
18435            while (it < NT && ir < NR) {
18436                if (curt == null) {
18437                    curt = (ResolveInfo)receivers.get(it);
18438                }
18439                if (curr == null) {
18440                    curr = registeredReceivers.get(ir);
18441                }
18442                if (curr.getPriority() >= curt.priority) {
18443                    // Insert this broadcast record into the final list.
18444                    receivers.add(it, curr);
18445                    ir++;
18446                    curr = null;
18447                    it++;
18448                    NT++;
18449                } else {
18450                    // Skip to the next ResolveInfo in the final list.
18451                    it++;
18452                    curt = null;
18453                }
18454            }
18455        }
18456        while (ir < NR) {
18457            if (receivers == null) {
18458                receivers = new ArrayList();
18459            }
18460            receivers.add(registeredReceivers.get(ir));
18461            ir++;
18462        }
18463
18464        if (isCallerSystem) {
18465            checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
18466                    isProtectedBroadcast, receivers);
18467        }
18468
18469        if ((receivers != null && receivers.size() > 0)
18470                || resultTo != null) {
18471            BroadcastQueue queue = broadcastQueueForIntent(intent);
18472            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18473                    callerPackage, callingPid, callingUid, resolvedType,
18474                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
18475                    resultData, resultExtras, ordered, sticky, false, userId);
18476
18477            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
18478                    + ": prev had " + queue.mOrderedBroadcasts.size());
18479            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
18480                    "Enqueueing broadcast " + r.intent.getAction());
18481
18482            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
18483            if (!replaced) {
18484                queue.enqueueOrderedBroadcastLocked(r);
18485                queue.scheduleBroadcastsLocked();
18486            }
18487        } else {
18488            // There was nobody interested in the broadcast, but we still want to record
18489            // that it happened.
18490            if (intent.getComponent() == null && intent.getPackage() == null
18491                    && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18492                // This was an implicit broadcast... let's record it for posterity.
18493                addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
18494            }
18495        }
18496
18497        return ActivityManager.BROADCAST_SUCCESS;
18498    }
18499
18500    final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
18501            int skipCount, long dispatchTime) {
18502        final long now = SystemClock.elapsedRealtime();
18503        if (mCurBroadcastStats == null ||
18504                (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
18505            mLastBroadcastStats = mCurBroadcastStats;
18506            if (mLastBroadcastStats != null) {
18507                mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
18508                mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
18509            }
18510            mCurBroadcastStats = new BroadcastStats();
18511        }
18512        mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
18513    }
18514
18515    final Intent verifyBroadcastLocked(Intent intent) {
18516        // Refuse possible leaked file descriptors
18517        if (intent != null && intent.hasFileDescriptors() == true) {
18518            throw new IllegalArgumentException("File descriptors passed in Intent");
18519        }
18520
18521        int flags = intent.getFlags();
18522
18523        if (!mProcessesReady) {
18524            // if the caller really truly claims to know what they're doing, go
18525            // ahead and allow the broadcast without launching any receivers
18526            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
18527                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
18528            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18529                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
18530                        + " before boot completion");
18531                throw new IllegalStateException("Cannot broadcast before boot completed");
18532            }
18533        }
18534
18535        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
18536            throw new IllegalArgumentException(
18537                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
18538        }
18539
18540        return intent;
18541    }
18542
18543    public final int broadcastIntent(IApplicationThread caller,
18544            Intent intent, String resolvedType, IIntentReceiver resultTo,
18545            int resultCode, String resultData, Bundle resultExtras,
18546            String[] requiredPermissions, int appOp, Bundle bOptions,
18547            boolean serialized, boolean sticky, int userId) {
18548        enforceNotIsolatedCaller("broadcastIntent");
18549        synchronized(this) {
18550            intent = verifyBroadcastLocked(intent);
18551
18552            final ProcessRecord callerApp = getRecordForAppLocked(caller);
18553            final int callingPid = Binder.getCallingPid();
18554            final int callingUid = Binder.getCallingUid();
18555            final long origId = Binder.clearCallingIdentity();
18556            int res = broadcastIntentLocked(callerApp,
18557                    callerApp != null ? callerApp.info.packageName : null,
18558                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
18559                    requiredPermissions, appOp, bOptions, serialized, sticky,
18560                    callingPid, callingUid, userId);
18561            Binder.restoreCallingIdentity(origId);
18562            return res;
18563        }
18564    }
18565
18566
18567    int broadcastIntentInPackage(String packageName, int uid,
18568            Intent intent, String resolvedType, IIntentReceiver resultTo,
18569            int resultCode, String resultData, Bundle resultExtras,
18570            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
18571            int userId) {
18572        synchronized(this) {
18573            intent = verifyBroadcastLocked(intent);
18574
18575            final long origId = Binder.clearCallingIdentity();
18576            String[] requiredPermissions = requiredPermission == null ? null
18577                    : new String[] {requiredPermission};
18578            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
18579                    resultTo, resultCode, resultData, resultExtras,
18580                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
18581                    sticky, -1, uid, userId);
18582            Binder.restoreCallingIdentity(origId);
18583            return res;
18584        }
18585    }
18586
18587    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
18588        // Refuse possible leaked file descriptors
18589        if (intent != null && intent.hasFileDescriptors() == true) {
18590            throw new IllegalArgumentException("File descriptors passed in Intent");
18591        }
18592
18593        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18594                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
18595
18596        synchronized(this) {
18597            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
18598                    != PackageManager.PERMISSION_GRANTED) {
18599                String msg = "Permission Denial: unbroadcastIntent() from pid="
18600                        + Binder.getCallingPid()
18601                        + ", uid=" + Binder.getCallingUid()
18602                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18603                Slog.w(TAG, msg);
18604                throw new SecurityException(msg);
18605            }
18606            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18607            if (stickies != null) {
18608                ArrayList<Intent> list = stickies.get(intent.getAction());
18609                if (list != null) {
18610                    int N = list.size();
18611                    int i;
18612                    for (i=0; i<N; i++) {
18613                        if (intent.filterEquals(list.get(i))) {
18614                            list.remove(i);
18615                            break;
18616                        }
18617                    }
18618                    if (list.size() <= 0) {
18619                        stickies.remove(intent.getAction());
18620                    }
18621                }
18622                if (stickies.size() <= 0) {
18623                    mStickyBroadcasts.remove(userId);
18624                }
18625            }
18626        }
18627    }
18628
18629    void backgroundServicesFinishedLocked(int userId) {
18630        for (BroadcastQueue queue : mBroadcastQueues) {
18631            queue.backgroundServicesFinishedLocked(userId);
18632        }
18633    }
18634
18635    public void finishReceiver(IBinder who, int resultCode, String resultData,
18636            Bundle resultExtras, boolean resultAbort, int flags) {
18637        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
18638
18639        // Refuse possible leaked file descriptors
18640        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
18641            throw new IllegalArgumentException("File descriptors passed in Bundle");
18642        }
18643
18644        final long origId = Binder.clearCallingIdentity();
18645        try {
18646            boolean doNext = false;
18647            BroadcastRecord r;
18648
18649            synchronized(this) {
18650                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
18651                        ? mFgBroadcastQueue : mBgBroadcastQueue;
18652                r = queue.getMatchingOrderedReceiver(who);
18653                if (r != null) {
18654                    doNext = r.queue.finishReceiverLocked(r, resultCode,
18655                        resultData, resultExtras, resultAbort, true);
18656                }
18657            }
18658
18659            if (doNext) {
18660                r.queue.processNextBroadcast(false);
18661            }
18662            trimApplications();
18663        } finally {
18664            Binder.restoreCallingIdentity(origId);
18665        }
18666    }
18667
18668    // =========================================================
18669    // INSTRUMENTATION
18670    // =========================================================
18671
18672    public boolean startInstrumentation(ComponentName className,
18673            String profileFile, int flags, Bundle arguments,
18674            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
18675            int userId, String abiOverride) {
18676        enforceNotIsolatedCaller("startInstrumentation");
18677        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18678                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
18679        // Refuse possible leaked file descriptors
18680        if (arguments != null && arguments.hasFileDescriptors()) {
18681            throw new IllegalArgumentException("File descriptors passed in Bundle");
18682        }
18683
18684        synchronized(this) {
18685            InstrumentationInfo ii = null;
18686            ApplicationInfo ai = null;
18687            try {
18688                ii = mContext.getPackageManager().getInstrumentationInfo(
18689                    className, STOCK_PM_FLAGS);
18690                ai = AppGlobals.getPackageManager().getApplicationInfo(
18691                        ii.targetPackage, STOCK_PM_FLAGS, userId);
18692            } catch (PackageManager.NameNotFoundException e) {
18693            } catch (RemoteException e) {
18694            }
18695            if (ii == null) {
18696                reportStartInstrumentationFailureLocked(watcher, className,
18697                        "Unable to find instrumentation info for: " + className);
18698                return false;
18699            }
18700            if (ai == null) {
18701                reportStartInstrumentationFailureLocked(watcher, className,
18702                        "Unable to find instrumentation target package: " + ii.targetPackage);
18703                return false;
18704            }
18705            if (!ai.hasCode()) {
18706                reportStartInstrumentationFailureLocked(watcher, className,
18707                        "Instrumentation target has no code: " + ii.targetPackage);
18708                return false;
18709            }
18710
18711            int match = mContext.getPackageManager().checkSignatures(
18712                    ii.targetPackage, ii.packageName);
18713            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18714                String msg = "Permission Denial: starting instrumentation "
18715                        + className + " from pid="
18716                        + Binder.getCallingPid()
18717                        + ", uid=" + Binder.getCallingPid()
18718                        + " not allowed because package " + ii.packageName
18719                        + " does not have a signature matching the target "
18720                        + ii.targetPackage;
18721                reportStartInstrumentationFailureLocked(watcher, className, msg);
18722                throw new SecurityException(msg);
18723            }
18724
18725            final long origId = Binder.clearCallingIdentity();
18726            // Instrumentation can kill and relaunch even persistent processes
18727            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18728                    "start instr");
18729            ProcessRecord app = addAppLocked(ai, false, abiOverride);
18730            app.instrumentationClass = className;
18731            app.instrumentationInfo = ai;
18732            app.instrumentationProfileFile = profileFile;
18733            app.instrumentationArguments = arguments;
18734            app.instrumentationWatcher = watcher;
18735            app.instrumentationUiAutomationConnection = uiAutomationConnection;
18736            app.instrumentationResultClass = className;
18737            Binder.restoreCallingIdentity(origId);
18738        }
18739
18740        return true;
18741    }
18742
18743    /**
18744     * Report errors that occur while attempting to start Instrumentation.  Always writes the
18745     * error to the logs, but if somebody is watching, send the report there too.  This enables
18746     * the "am" command to report errors with more information.
18747     *
18748     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
18749     * @param cn The component name of the instrumentation.
18750     * @param report The error report.
18751     */
18752    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18753            ComponentName cn, String report) {
18754        Slog.w(TAG, report);
18755        if (watcher != null) {
18756            Bundle results = new Bundle();
18757            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18758            results.putString("Error", report);
18759            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18760        }
18761    }
18762
18763    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18764        if (app.instrumentationWatcher != null) {
18765            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18766                    app.instrumentationClass, resultCode, results);
18767        }
18768
18769        // Can't call out of the system process with a lock held, so post a message.
18770        if (app.instrumentationUiAutomationConnection != null) {
18771            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18772                    app.instrumentationUiAutomationConnection).sendToTarget();
18773        }
18774
18775        app.instrumentationWatcher = null;
18776        app.instrumentationUiAutomationConnection = null;
18777        app.instrumentationClass = null;
18778        app.instrumentationInfo = null;
18779        app.instrumentationProfileFile = null;
18780        app.instrumentationArguments = null;
18781
18782        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18783                "finished inst");
18784    }
18785
18786    public void finishInstrumentation(IApplicationThread target,
18787            int resultCode, Bundle results) {
18788        int userId = UserHandle.getCallingUserId();
18789        // Refuse possible leaked file descriptors
18790        if (results != null && results.hasFileDescriptors()) {
18791            throw new IllegalArgumentException("File descriptors passed in Intent");
18792        }
18793
18794        synchronized(this) {
18795            ProcessRecord app = getRecordForAppLocked(target);
18796            if (app == null) {
18797                Slog.w(TAG, "finishInstrumentation: no app for " + target);
18798                return;
18799            }
18800            final long origId = Binder.clearCallingIdentity();
18801            finishInstrumentationLocked(app, resultCode, results);
18802            Binder.restoreCallingIdentity(origId);
18803        }
18804    }
18805
18806    // =========================================================
18807    // CONFIGURATION
18808    // =========================================================
18809
18810    public ConfigurationInfo getDeviceConfigurationInfo() {
18811        ConfigurationInfo config = new ConfigurationInfo();
18812        synchronized (this) {
18813            config.reqTouchScreen = mConfiguration.touchscreen;
18814            config.reqKeyboardType = mConfiguration.keyboard;
18815            config.reqNavigation = mConfiguration.navigation;
18816            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18817                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18818                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18819            }
18820            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18821                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18822                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18823            }
18824            config.reqGlEsVersion = GL_ES_VERSION;
18825        }
18826        return config;
18827    }
18828
18829    ActivityStack getFocusedStack() {
18830        return mStackSupervisor.getFocusedStack();
18831    }
18832
18833    @Override
18834    public int getFocusedStackId() throws RemoteException {
18835        ActivityStack focusedStack = getFocusedStack();
18836        if (focusedStack != null) {
18837            return focusedStack.getStackId();
18838        }
18839        return -1;
18840    }
18841
18842    public Configuration getConfiguration() {
18843        Configuration ci;
18844        synchronized(this) {
18845            ci = new Configuration(mConfiguration);
18846            ci.userSetLocale = false;
18847        }
18848        return ci;
18849    }
18850
18851    @Override
18852    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18853        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18854        synchronized (this) {
18855            mSuppressResizeConfigChanges = suppress;
18856        }
18857    }
18858
18859    @Override
18860    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18861        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18862        if (fromStackId == HOME_STACK_ID) {
18863            throw new IllegalArgumentException("You can't move tasks from the home stack.");
18864        }
18865        synchronized (this) {
18866            final long origId = Binder.clearCallingIdentity();
18867            try {
18868                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18869            } finally {
18870                Binder.restoreCallingIdentity(origId);
18871            }
18872        }
18873    }
18874
18875    @Override
18876    public void updatePersistentConfiguration(Configuration values) {
18877        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18878                "updateConfiguration()");
18879        enforceWriteSettingsPermission("updateConfiguration()");
18880        if (values == null) {
18881            throw new NullPointerException("Configuration must not be null");
18882        }
18883
18884        int userId = UserHandle.getCallingUserId();
18885
18886        synchronized(this) {
18887            updatePersistentConfigurationLocked(values, userId);
18888        }
18889    }
18890
18891    private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
18892        final long origId = Binder.clearCallingIdentity();
18893        try {
18894            updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
18895        } finally {
18896            Binder.restoreCallingIdentity(origId);
18897        }
18898    }
18899
18900    private void updateFontScaleIfNeeded(@UserIdInt int userId) {
18901        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18902                FONT_SCALE, 1.0f, userId);
18903        if (mConfiguration.fontScale != scaleFactor) {
18904            final Configuration configuration = mWindowManager.computeNewConfiguration();
18905            configuration.fontScale = scaleFactor;
18906            synchronized (this) {
18907                updatePersistentConfigurationLocked(configuration, userId);
18908            }
18909        }
18910    }
18911
18912    private void enforceWriteSettingsPermission(String func) {
18913        int uid = Binder.getCallingUid();
18914        if (uid == Process.ROOT_UID) {
18915            return;
18916        }
18917
18918        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18919                Settings.getPackageNameForUid(mContext, uid), false)) {
18920            return;
18921        }
18922
18923        String msg = "Permission Denial: " + func + " from pid="
18924                + Binder.getCallingPid()
18925                + ", uid=" + uid
18926                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18927        Slog.w(TAG, msg);
18928        throw new SecurityException(msg);
18929    }
18930
18931    public void updateConfiguration(Configuration values) {
18932        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18933                "updateConfiguration()");
18934
18935        synchronized(this) {
18936            if (values == null && mWindowManager != null) {
18937                // sentinel: fetch the current configuration from the window manager
18938                values = mWindowManager.computeNewConfiguration();
18939            }
18940
18941            if (mWindowManager != null) {
18942                mProcessList.applyDisplaySize(mWindowManager);
18943            }
18944
18945            final long origId = Binder.clearCallingIdentity();
18946            if (values != null) {
18947                Settings.System.clearConfiguration(values);
18948            }
18949            updateConfigurationLocked(values, null, false);
18950            Binder.restoreCallingIdentity(origId);
18951        }
18952    }
18953
18954    void updateUserConfigurationLocked() {
18955        Configuration configuration = new Configuration(mConfiguration);
18956        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
18957                mUserController.getCurrentUserIdLocked(), Settings.System.canWrite(mContext));
18958        updateConfigurationLocked(configuration, null, false);
18959    }
18960
18961    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
18962            boolean initLocale) {
18963        return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
18964    }
18965
18966    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
18967            boolean initLocale, boolean deferResume) {
18968        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18969        return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
18970                UserHandle.USER_NULL, deferResume);
18971    }
18972
18973    // To cache the list of supported system locales
18974    private String[] mSupportedSystemLocales = null;
18975
18976    /**
18977     * Do either or both things: (1) change the current configuration, and (2)
18978     * make sure the given activity is running with the (now) current
18979     * configuration.  Returns true if the activity has been left running, or
18980     * false if <var>starting</var> is being destroyed to match the new
18981     * configuration.
18982     *
18983     * @param userId is only used when persistent parameter is set to true to persist configuration
18984     *               for that particular user
18985     */
18986    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
18987            boolean initLocale, boolean persistent, int userId, boolean deferResume) {
18988        int changes = 0;
18989
18990        if (mWindowManager != null) {
18991            mWindowManager.deferSurfaceLayout();
18992        }
18993        if (values != null) {
18994            Configuration newConfig = new Configuration(mConfiguration);
18995            changes = newConfig.updateFrom(values);
18996            if (changes != 0) {
18997                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18998                        "Updating configuration to: " + values);
18999
19000                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
19001
19002                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
19003                    final LocaleList locales = values.getLocales();
19004                    int bestLocaleIndex = 0;
19005                    if (locales.size() > 1) {
19006                        if (mSupportedSystemLocales == null) {
19007                            mSupportedSystemLocales =
19008                                    Resources.getSystem().getAssets().getLocales();
19009                        }
19010                        bestLocaleIndex = Math.max(0,
19011                                locales.getFirstMatchIndex(mSupportedSystemLocales));
19012                    }
19013                    SystemProperties.set("persist.sys.locale",
19014                            locales.get(bestLocaleIndex).toLanguageTag());
19015                    LocaleList.setDefault(locales, bestLocaleIndex);
19016                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
19017                            locales.get(bestLocaleIndex)));
19018                }
19019
19020                mConfigurationSeq++;
19021                if (mConfigurationSeq <= 0) {
19022                    mConfigurationSeq = 1;
19023                }
19024                newConfig.seq = mConfigurationSeq;
19025                mConfiguration = newConfig;
19026                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
19027                mUsageStatsService.reportConfigurationChange(newConfig,
19028                        mUserController.getCurrentUserIdLocked());
19029                //mUsageStatsService.noteStartConfig(newConfig);
19030
19031                final Configuration configCopy = new Configuration(mConfiguration);
19032
19033                // TODO: If our config changes, should we auto dismiss any currently
19034                // showing dialogs?
19035                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
19036
19037                AttributeCache ac = AttributeCache.instance();
19038                if (ac != null) {
19039                    ac.updateConfiguration(configCopy);
19040                }
19041
19042                // Make sure all resources in our process are updated
19043                // right now, so that anyone who is going to retrieve
19044                // resource values after we return will be sure to get
19045                // the new ones.  This is especially important during
19046                // boot, where the first config change needs to guarantee
19047                // all resources have that config before following boot
19048                // code is executed.
19049                mSystemThread.applyConfigurationToResources(configCopy);
19050
19051                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
19052                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
19053                    msg.obj = new Configuration(configCopy);
19054                    msg.arg1 = userId;
19055                    mHandler.sendMessage(msg);
19056                }
19057
19058                final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
19059                if (isDensityChange) {
19060                    // Reset the unsupported display size dialog.
19061                    mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
19062
19063                    killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
19064                            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
19065                }
19066
19067                for (int i=mLruProcesses.size()-1; i>=0; i--) {
19068                    ProcessRecord app = mLruProcesses.get(i);
19069                    try {
19070                        if (app.thread != null) {
19071                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
19072                                    + app.processName + " new config " + mConfiguration);
19073                            app.thread.scheduleConfigurationChanged(configCopy);
19074                        }
19075                    } catch (Exception e) {
19076                    }
19077                }
19078                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
19079                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19080                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
19081                        | Intent.FLAG_RECEIVER_FOREGROUND);
19082                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
19083                        null, AppOpsManager.OP_NONE, null, false, false,
19084                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19085                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
19086                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
19087                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
19088	            if (initLocale || !mProcessesReady) {
19089                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19090                    }
19091                    broadcastIntentLocked(null, null, intent,
19092                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19093                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19094                }
19095            }
19096            // Update the configuration with WM first and check if any of the stacks need to be
19097            // resized due to the configuration change. If so, resize the stacks now and do any
19098            // relaunches if necessary. This way we don't need to relaunch again below in
19099            // ensureActivityConfigurationLocked().
19100            if (mWindowManager != null) {
19101                final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
19102                if (resizedStacks != null) {
19103                    for (int stackId : resizedStacks) {
19104                        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
19105                        mStackSupervisor.resizeStackLocked(
19106                                stackId, newBounds, null, null, false, false, deferResume);
19107                    }
19108                }
19109            }
19110        }
19111
19112        boolean kept = true;
19113        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
19114        // mainStack is null during startup.
19115        if (mainStack != null) {
19116            if (changes != 0 && starting == null) {
19117                // If the configuration changed, and the caller is not already
19118                // in the process of starting an activity, then find the top
19119                // activity to check if its configuration needs to change.
19120                starting = mainStack.topRunningActivityLocked();
19121            }
19122
19123            if (starting != null) {
19124                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
19125                // And we need to make sure at this point that all other activities
19126                // are made visible with the correct configuration.
19127                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
19128                        !PRESERVE_WINDOWS);
19129            }
19130        }
19131        if (mWindowManager != null) {
19132            mWindowManager.continueSurfaceLayout();
19133        }
19134        return kept;
19135    }
19136
19137    /**
19138     * Decide based on the configuration whether we should shouw the ANR,
19139     * crash, etc dialogs.  The idea is that if there is no affordence to
19140     * press the on-screen buttons, or the user experience would be more
19141     * greatly impacted than the crash itself, we shouldn't show the dialog.
19142     *
19143     * A thought: SystemUI might also want to get told about this, the Power
19144     * dialog / global actions also might want different behaviors.
19145     */
19146    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
19147        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
19148                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
19149                                   && config.navigation == Configuration.NAVIGATION_NONAV);
19150        int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
19151        final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
19152                && !(modeType == Configuration.UI_MODE_TYPE_WATCH && "user".equals(Build.TYPE)));
19153        return inputMethodExists && uiModeSupportsDialogs && !inVrMode;
19154    }
19155
19156    @Override
19157    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
19158        synchronized (this) {
19159            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
19160            if (srec != null) {
19161                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
19162            }
19163        }
19164        return false;
19165    }
19166
19167    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
19168            Intent resultData) {
19169
19170        synchronized (this) {
19171            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
19172            if (r != null) {
19173                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
19174            }
19175            return false;
19176        }
19177    }
19178
19179    public int getLaunchedFromUid(IBinder activityToken) {
19180        ActivityRecord srec;
19181        synchronized (this) {
19182            srec = ActivityRecord.forTokenLocked(activityToken);
19183        }
19184        if (srec == null) {
19185            return -1;
19186        }
19187        return srec.launchedFromUid;
19188    }
19189
19190    public String getLaunchedFromPackage(IBinder activityToken) {
19191        ActivityRecord srec;
19192        synchronized (this) {
19193            srec = ActivityRecord.forTokenLocked(activityToken);
19194        }
19195        if (srec == null) {
19196            return null;
19197        }
19198        return srec.launchedFromPackage;
19199    }
19200
19201    // =========================================================
19202    // LIFETIME MANAGEMENT
19203    // =========================================================
19204
19205    // Returns whether the app is receiving broadcast.
19206    // If receiving, fetch all broadcast queues which the app is
19207    // the current [or imminent] receiver on.
19208    private boolean isReceivingBroadcastLocked(ProcessRecord app,
19209            ArraySet<BroadcastQueue> receivingQueues) {
19210        if (!app.curReceivers.isEmpty()) {
19211            for (BroadcastRecord r : app.curReceivers) {
19212                receivingQueues.add(r.queue);
19213            }
19214            return true;
19215        }
19216
19217        // It's not the current receiver, but it might be starting up to become one
19218        for (BroadcastQueue queue : mBroadcastQueues) {
19219            final BroadcastRecord r = queue.mPendingBroadcast;
19220            if (r != null && r.curApp == app) {
19221                // found it; report which queue it's in
19222                receivingQueues.add(queue);
19223            }
19224        }
19225
19226        return !receivingQueues.isEmpty();
19227    }
19228
19229    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
19230            int targetUid, ComponentName targetComponent, String targetProcess) {
19231        if (!mTrackingAssociations) {
19232            return null;
19233        }
19234        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19235                = mAssociations.get(targetUid);
19236        if (components == null) {
19237            components = new ArrayMap<>();
19238            mAssociations.put(targetUid, components);
19239        }
19240        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19241        if (sourceUids == null) {
19242            sourceUids = new SparseArray<>();
19243            components.put(targetComponent, sourceUids);
19244        }
19245        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19246        if (sourceProcesses == null) {
19247            sourceProcesses = new ArrayMap<>();
19248            sourceUids.put(sourceUid, sourceProcesses);
19249        }
19250        Association ass = sourceProcesses.get(sourceProcess);
19251        if (ass == null) {
19252            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
19253                    targetProcess);
19254            sourceProcesses.put(sourceProcess, ass);
19255        }
19256        ass.mCount++;
19257        ass.mNesting++;
19258        if (ass.mNesting == 1) {
19259            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
19260            ass.mLastState = sourceState;
19261        }
19262        return ass;
19263    }
19264
19265    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
19266            ComponentName targetComponent) {
19267        if (!mTrackingAssociations) {
19268            return;
19269        }
19270        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19271                = mAssociations.get(targetUid);
19272        if (components == null) {
19273            return;
19274        }
19275        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19276        if (sourceUids == null) {
19277            return;
19278        }
19279        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19280        if (sourceProcesses == null) {
19281            return;
19282        }
19283        Association ass = sourceProcesses.get(sourceProcess);
19284        if (ass == null || ass.mNesting <= 0) {
19285            return;
19286        }
19287        ass.mNesting--;
19288        if (ass.mNesting == 0) {
19289            long uptime = SystemClock.uptimeMillis();
19290            ass.mTime += uptime - ass.mStartTime;
19291            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19292                    += uptime - ass.mLastStateUptime;
19293            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
19294        }
19295    }
19296
19297    private void noteUidProcessState(final int uid, final int state) {
19298        mBatteryStatsService.noteUidProcessState(uid, state);
19299        if (mTrackingAssociations) {
19300            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
19301                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
19302                        = mAssociations.valueAt(i1);
19303                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
19304                    SparseArray<ArrayMap<String, Association>> sourceUids
19305                            = targetComponents.valueAt(i2);
19306                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
19307                    if (sourceProcesses != null) {
19308                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
19309                            Association ass = sourceProcesses.valueAt(i4);
19310                            if (ass.mNesting >= 1) {
19311                                // currently associated
19312                                long uptime = SystemClock.uptimeMillis();
19313                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19314                                        += uptime - ass.mLastStateUptime;
19315                                ass.mLastState = state;
19316                                ass.mLastStateUptime = uptime;
19317                            }
19318                        }
19319                    }
19320                }
19321            }
19322        }
19323    }
19324
19325    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
19326            boolean doingAll, long now) {
19327        if (mAdjSeq == app.adjSeq) {
19328            // This adjustment has already been computed.
19329            return app.curRawAdj;
19330        }
19331
19332        if (app.thread == null) {
19333            app.adjSeq = mAdjSeq;
19334            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19335            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19336            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
19337        }
19338
19339        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
19340        app.adjSource = null;
19341        app.adjTarget = null;
19342        app.empty = false;
19343        app.cached = false;
19344
19345        final int activitiesSize = app.activities.size();
19346
19347        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19348            // The max adjustment doesn't allow this app to be anything
19349            // below foreground, so it is not worth doing work for it.
19350            app.adjType = "fixed";
19351            app.adjSeq = mAdjSeq;
19352            app.curRawAdj = app.maxAdj;
19353            app.foregroundActivities = false;
19354            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19355            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
19356            // System processes can do UI, and when they do we want to have
19357            // them trim their memory after the user leaves the UI.  To
19358            // facilitate this, here we need to determine whether or not it
19359            // is currently showing UI.
19360            app.systemNoUi = true;
19361            if (app == TOP_APP) {
19362                app.systemNoUi = false;
19363                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19364                app.adjType = "pers-top-activity";
19365            } else if (app.hasTopUi) {
19366                app.systemNoUi = false;
19367                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19368                app.adjType = "pers-top-ui";
19369            } else if (activitiesSize > 0) {
19370                for (int j = 0; j < activitiesSize; j++) {
19371                    final ActivityRecord r = app.activities.get(j);
19372                    if (r.visible) {
19373                        app.systemNoUi = false;
19374                    }
19375                }
19376            }
19377            if (!app.systemNoUi) {
19378                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
19379            }
19380            return (app.curAdj=app.maxAdj);
19381        }
19382
19383        app.systemNoUi = false;
19384
19385        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
19386
19387        // Determine the importance of the process, starting with most
19388        // important to least, and assign an appropriate OOM adjustment.
19389        int adj;
19390        int schedGroup;
19391        int procState;
19392        boolean foregroundActivities = false;
19393        final ArraySet<BroadcastQueue> queues = new ArraySet<BroadcastQueue>();
19394        if (app == TOP_APP) {
19395            // The last app on the list is the foreground app.
19396            adj = ProcessList.FOREGROUND_APP_ADJ;
19397            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19398            app.adjType = "top-activity";
19399            foregroundActivities = true;
19400            procState = PROCESS_STATE_CUR_TOP;
19401        } else if (app.instrumentationClass != null) {
19402            // Don't want to kill running instrumentation.
19403            adj = ProcessList.FOREGROUND_APP_ADJ;
19404            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19405            app.adjType = "instrumentation";
19406            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19407        } else if (isReceivingBroadcastLocked(app, queues)) {
19408            // An app that is currently receiving a broadcast also
19409            // counts as being in the foreground for OOM killer purposes.
19410            // It's placed in a sched group based on the nature of the
19411            // broadcast as reflected by which queue it's active in.
19412            adj = ProcessList.FOREGROUND_APP_ADJ;
19413            schedGroup = (queues.contains(mFgBroadcastQueue))
19414                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19415            app.adjType = "broadcast";
19416            procState = ActivityManager.PROCESS_STATE_RECEIVER;
19417        } else if (app.executingServices.size() > 0) {
19418            // An app that is currently executing a service callback also
19419            // counts as being in the foreground.
19420            adj = ProcessList.FOREGROUND_APP_ADJ;
19421            schedGroup = app.execServicesFg ?
19422                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19423            app.adjType = "exec-service";
19424            procState = ActivityManager.PROCESS_STATE_SERVICE;
19425            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
19426        } else {
19427            // As far as we know the process is empty.  We may change our mind later.
19428            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19429            // At this point we don't actually know the adjustment.  Use the cached adj
19430            // value that the caller wants us to.
19431            adj = cachedAdj;
19432            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19433            app.cached = true;
19434            app.empty = true;
19435            app.adjType = "cch-empty";
19436        }
19437
19438        // Examine all activities if not already foreground.
19439        if (!foregroundActivities && activitiesSize > 0) {
19440            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
19441            for (int j = 0; j < activitiesSize; j++) {
19442                final ActivityRecord r = app.activities.get(j);
19443                if (r.app != app) {
19444                    Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
19445                            + " instead of expected " + app);
19446                    if (r.app == null || (r.app.uid == app.uid)) {
19447                        // Only fix things up when they look sane
19448                        r.app = app;
19449                    } else {
19450                        continue;
19451                    }
19452                }
19453                if (r.visible) {
19454                    // App has a visible activity; only upgrade adjustment.
19455                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19456                        adj = ProcessList.VISIBLE_APP_ADJ;
19457                        app.adjType = "visible";
19458                    }
19459                    if (procState > PROCESS_STATE_CUR_TOP) {
19460                        procState = PROCESS_STATE_CUR_TOP;
19461                    }
19462                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19463                    app.cached = false;
19464                    app.empty = false;
19465                    foregroundActivities = true;
19466                    if (r.task != null && minLayer > 0) {
19467                        final int layer = r.task.mLayerRank;
19468                        if (layer >= 0 && minLayer > layer) {
19469                            minLayer = layer;
19470                        }
19471                    }
19472                    break;
19473                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
19474                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19475                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19476                        app.adjType = "pausing";
19477                    }
19478                    if (procState > PROCESS_STATE_CUR_TOP) {
19479                        procState = PROCESS_STATE_CUR_TOP;
19480                    }
19481                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19482                    app.cached = false;
19483                    app.empty = false;
19484                    foregroundActivities = true;
19485                } else if (r.state == ActivityState.STOPPING) {
19486                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19487                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19488                        app.adjType = "stopping";
19489                    }
19490                    // For the process state, we will at this point consider the
19491                    // process to be cached.  It will be cached either as an activity
19492                    // or empty depending on whether the activity is finishing.  We do
19493                    // this so that we can treat the process as cached for purposes of
19494                    // memory trimming (determing current memory level, trim command to
19495                    // send to process) since there can be an arbitrary number of stopping
19496                    // processes and they should soon all go into the cached state.
19497                    if (!r.finishing) {
19498                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19499                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19500                        }
19501                    }
19502                    app.cached = false;
19503                    app.empty = false;
19504                    foregroundActivities = true;
19505                } else {
19506                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19507                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19508                        app.adjType = "cch-act";
19509                    }
19510                }
19511            }
19512            if (adj == ProcessList.VISIBLE_APP_ADJ) {
19513                adj += minLayer;
19514            }
19515        }
19516
19517        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
19518                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
19519            if (app.foregroundServices) {
19520                // The user is aware of this app, so make it visible.
19521                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19522                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19523                app.cached = false;
19524                app.adjType = "fg-service";
19525                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19526            } else if (app.forcingToForeground != null) {
19527                // The user is aware of this app, so make it visible.
19528                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19529                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19530                app.cached = false;
19531                app.adjType = "force-fg";
19532                app.adjSource = app.forcingToForeground;
19533                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19534            }
19535        }
19536
19537        if (app == mHeavyWeightProcess) {
19538            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
19539                // We don't want to kill the current heavy-weight process.
19540                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
19541                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19542                app.cached = false;
19543                app.adjType = "heavy";
19544            }
19545            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19546                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
19547            }
19548        }
19549
19550        if (app == mHomeProcess) {
19551            if (adj > ProcessList.HOME_APP_ADJ) {
19552                // This process is hosting what we currently consider to be the
19553                // home app, so we don't want to let it go into the background.
19554                adj = ProcessList.HOME_APP_ADJ;
19555                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19556                app.cached = false;
19557                app.adjType = "home";
19558            }
19559            if (procState > ActivityManager.PROCESS_STATE_HOME) {
19560                procState = ActivityManager.PROCESS_STATE_HOME;
19561            }
19562        }
19563
19564        if (app == mPreviousProcess && app.activities.size() > 0) {
19565            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19566                // This was the previous process that showed UI to the user.
19567                // We want to try to keep it around more aggressively, to give
19568                // a good experience around switching between two apps.
19569                adj = ProcessList.PREVIOUS_APP_ADJ;
19570                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19571                app.cached = false;
19572                app.adjType = "previous";
19573            }
19574            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19575                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19576            }
19577        }
19578
19579        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
19580                + " reason=" + app.adjType);
19581
19582        // By default, we use the computed adjustment.  It may be changed if
19583        // there are applications dependent on our services or providers, but
19584        // this gives us a baseline and makes sure we don't get into an
19585        // infinite recursion.
19586        app.adjSeq = mAdjSeq;
19587        app.curRawAdj = adj;
19588        app.hasStartedServices = false;
19589
19590        if (mBackupTarget != null && app == mBackupTarget.app) {
19591            // If possible we want to avoid killing apps while they're being backed up
19592            if (adj > ProcessList.BACKUP_APP_ADJ) {
19593                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
19594                adj = ProcessList.BACKUP_APP_ADJ;
19595                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19596                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19597                }
19598                app.adjType = "backup";
19599                app.cached = false;
19600            }
19601            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
19602                procState = ActivityManager.PROCESS_STATE_BACKUP;
19603            }
19604        }
19605
19606        boolean mayBeTop = false;
19607
19608        for (int is = app.services.size()-1;
19609                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19610                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19611                        || procState > ActivityManager.PROCESS_STATE_TOP);
19612                is--) {
19613            ServiceRecord s = app.services.valueAt(is);
19614            if (s.startRequested) {
19615                app.hasStartedServices = true;
19616                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
19617                    procState = ActivityManager.PROCESS_STATE_SERVICE;
19618                }
19619                if (app.hasShownUi && app != mHomeProcess) {
19620                    // If this process has shown some UI, let it immediately
19621                    // go to the LRU list because it may be pretty heavy with
19622                    // UI stuff.  We'll tag it with a label just to help
19623                    // debug and understand what is going on.
19624                    if (adj > ProcessList.SERVICE_ADJ) {
19625                        app.adjType = "cch-started-ui-services";
19626                    }
19627                } else {
19628                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19629                        // This service has seen some activity within
19630                        // recent memory, so we will keep its process ahead
19631                        // of the background processes.
19632                        if (adj > ProcessList.SERVICE_ADJ) {
19633                            adj = ProcessList.SERVICE_ADJ;
19634                            app.adjType = "started-services";
19635                            app.cached = false;
19636                        }
19637                    }
19638                    // If we have let the service slide into the background
19639                    // state, still have some text describing what it is doing
19640                    // even though the service no longer has an impact.
19641                    if (adj > ProcessList.SERVICE_ADJ) {
19642                        app.adjType = "cch-started-services";
19643                    }
19644                }
19645            }
19646
19647            for (int conni = s.connections.size()-1;
19648                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19649                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19650                            || procState > ActivityManager.PROCESS_STATE_TOP);
19651                    conni--) {
19652                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
19653                for (int i = 0;
19654                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
19655                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19656                                || procState > ActivityManager.PROCESS_STATE_TOP);
19657                        i++) {
19658                    // XXX should compute this based on the max of
19659                    // all connected clients.
19660                    ConnectionRecord cr = clist.get(i);
19661                    if (cr.binding.client == app) {
19662                        // Binding to ourself is not interesting.
19663                        continue;
19664                    }
19665
19666                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
19667                        ProcessRecord client = cr.binding.client;
19668                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
19669                                TOP_APP, doingAll, now);
19670                        int clientProcState = client.curProcState;
19671                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19672                            // If the other app is cached for any reason, for purposes here
19673                            // we are going to consider it empty.  The specific cached state
19674                            // doesn't propagate except under certain conditions.
19675                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19676                        }
19677                        String adjType = null;
19678                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
19679                            // Not doing bind OOM management, so treat
19680                            // this guy more like a started service.
19681                            if (app.hasShownUi && app != mHomeProcess) {
19682                                // If this process has shown some UI, let it immediately
19683                                // go to the LRU list because it may be pretty heavy with
19684                                // UI stuff.  We'll tag it with a label just to help
19685                                // debug and understand what is going on.
19686                                if (adj > clientAdj) {
19687                                    adjType = "cch-bound-ui-services";
19688                                }
19689                                app.cached = false;
19690                                clientAdj = adj;
19691                                clientProcState = procState;
19692                            } else {
19693                                if (now >= (s.lastActivity
19694                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19695                                    // This service has not seen activity within
19696                                    // recent memory, so allow it to drop to the
19697                                    // LRU list if there is no other reason to keep
19698                                    // it around.  We'll also tag it with a label just
19699                                    // to help debug and undertand what is going on.
19700                                    if (adj > clientAdj) {
19701                                        adjType = "cch-bound-services";
19702                                    }
19703                                    clientAdj = adj;
19704                                }
19705                            }
19706                        }
19707                        if (adj > clientAdj) {
19708                            // If this process has recently shown UI, and
19709                            // the process that is binding to it is less
19710                            // important than being visible, then we don't
19711                            // care about the binding as much as we care
19712                            // about letting this process get into the LRU
19713                            // list to be killed and restarted if needed for
19714                            // memory.
19715                            if (app.hasShownUi && app != mHomeProcess
19716                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19717                                adjType = "cch-bound-ui-services";
19718                            } else {
19719                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
19720                                        |Context.BIND_IMPORTANT)) != 0) {
19721                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
19722                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
19723                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
19724                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
19725                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19726                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19727                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
19728                                    adj = clientAdj;
19729                                } else {
19730                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19731                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
19732                                    }
19733                                }
19734                                if (!client.cached) {
19735                                    app.cached = false;
19736                                }
19737                                adjType = "service";
19738                            }
19739                        }
19740                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19741                            // This will treat important bound services identically to
19742                            // the top app, which may behave differently than generic
19743                            // foreground work.
19744                            if (client.curSchedGroup > schedGroup) {
19745                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19746                                    schedGroup = client.curSchedGroup;
19747                                } else {
19748                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19749                                }
19750                            }
19751                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19752                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19753                                    // Special handling of clients who are in the top state.
19754                                    // We *may* want to consider this process to be in the
19755                                    // top state as well, but only if there is not another
19756                                    // reason for it to be running.  Being on the top is a
19757                                    // special state, meaning you are specifically running
19758                                    // for the current top app.  If the process is already
19759                                    // running in the background for some other reason, it
19760                                    // is more important to continue considering it to be
19761                                    // in the background state.
19762                                    mayBeTop = true;
19763                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19764                                } else {
19765                                    // Special handling for above-top states (persistent
19766                                    // processes).  These should not bring the current process
19767                                    // into the top state, since they are not on top.  Instead
19768                                    // give them the best state after that.
19769                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
19770                                        clientProcState =
19771                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19772                                    } else if (mWakefulness
19773                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
19774                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
19775                                                    != 0) {
19776                                        clientProcState =
19777                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19778                                    } else {
19779                                        clientProcState =
19780                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19781                                    }
19782                                }
19783                            }
19784                        } else {
19785                            if (clientProcState <
19786                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19787                                clientProcState =
19788                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19789                            }
19790                        }
19791                        if (procState > clientProcState) {
19792                            procState = clientProcState;
19793                        }
19794                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19795                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
19796                            app.pendingUiClean = true;
19797                        }
19798                        if (adjType != null) {
19799                            app.adjType = adjType;
19800                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19801                                    .REASON_SERVICE_IN_USE;
19802                            app.adjSource = cr.binding.client;
19803                            app.adjSourceProcState = clientProcState;
19804                            app.adjTarget = s.name;
19805                        }
19806                    }
19807                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
19808                        app.treatLikeActivity = true;
19809                    }
19810                    final ActivityRecord a = cr.activity;
19811                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
19812                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19813                            (a.visible || a.state == ActivityState.RESUMED ||
19814                             a.state == ActivityState.PAUSING)) {
19815                            adj = ProcessList.FOREGROUND_APP_ADJ;
19816                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19817                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19818                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
19819                                } else {
19820                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19821                                }
19822                            }
19823                            app.cached = false;
19824                            app.adjType = "service";
19825                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19826                                    .REASON_SERVICE_IN_USE;
19827                            app.adjSource = a;
19828                            app.adjSourceProcState = procState;
19829                            app.adjTarget = s.name;
19830                        }
19831                    }
19832                }
19833            }
19834        }
19835
19836        for (int provi = app.pubProviders.size()-1;
19837                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19838                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19839                        || procState > ActivityManager.PROCESS_STATE_TOP);
19840                provi--) {
19841            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19842            for (int i = cpr.connections.size()-1;
19843                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19844                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19845                            || procState > ActivityManager.PROCESS_STATE_TOP);
19846                    i--) {
19847                ContentProviderConnection conn = cpr.connections.get(i);
19848                ProcessRecord client = conn.client;
19849                if (client == app) {
19850                    // Being our own client is not interesting.
19851                    continue;
19852                }
19853                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19854                int clientProcState = client.curProcState;
19855                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19856                    // If the other app is cached for any reason, for purposes here
19857                    // we are going to consider it empty.
19858                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19859                }
19860                if (adj > clientAdj) {
19861                    if (app.hasShownUi && app != mHomeProcess
19862                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19863                        app.adjType = "cch-ui-provider";
19864                    } else {
19865                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19866                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19867                        app.adjType = "provider";
19868                    }
19869                    app.cached &= client.cached;
19870                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19871                            .REASON_PROVIDER_IN_USE;
19872                    app.adjSource = client;
19873                    app.adjSourceProcState = clientProcState;
19874                    app.adjTarget = cpr.name;
19875                }
19876                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19877                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19878                        // Special handling of clients who are in the top state.
19879                        // We *may* want to consider this process to be in the
19880                        // top state as well, but only if there is not another
19881                        // reason for it to be running.  Being on the top is a
19882                        // special state, meaning you are specifically running
19883                        // for the current top app.  If the process is already
19884                        // running in the background for some other reason, it
19885                        // is more important to continue considering it to be
19886                        // in the background state.
19887                        mayBeTop = true;
19888                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19889                    } else {
19890                        // Special handling for above-top states (persistent
19891                        // processes).  These should not bring the current process
19892                        // into the top state, since they are not on top.  Instead
19893                        // give them the best state after that.
19894                        clientProcState =
19895                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19896                    }
19897                }
19898                if (procState > clientProcState) {
19899                    procState = clientProcState;
19900                }
19901                if (client.curSchedGroup > schedGroup) {
19902                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19903                }
19904            }
19905            // If the provider has external (non-framework) process
19906            // dependencies, ensure that its adjustment is at least
19907            // FOREGROUND_APP_ADJ.
19908            if (cpr.hasExternalProcessHandles()) {
19909                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19910                    adj = ProcessList.FOREGROUND_APP_ADJ;
19911                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19912                    app.cached = false;
19913                    app.adjType = "provider";
19914                    app.adjTarget = cpr.name;
19915                }
19916                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19917                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19918                }
19919            }
19920        }
19921
19922        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19923            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19924                adj = ProcessList.PREVIOUS_APP_ADJ;
19925                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19926                app.cached = false;
19927                app.adjType = "provider";
19928            }
19929            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19930                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19931            }
19932        }
19933
19934        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19935            // A client of one of our services or providers is in the top state.  We
19936            // *may* want to be in the top state, but not if we are already running in
19937            // the background for some other reason.  For the decision here, we are going
19938            // to pick out a few specific states that we want to remain in when a client
19939            // is top (states that tend to be longer-term) and otherwise allow it to go
19940            // to the top state.
19941            switch (procState) {
19942                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19943                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19944                case ActivityManager.PROCESS_STATE_SERVICE:
19945                    // These all are longer-term states, so pull them up to the top
19946                    // of the background states, but not all the way to the top state.
19947                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19948                    break;
19949                default:
19950                    // Otherwise, top is a better choice, so take it.
19951                    procState = ActivityManager.PROCESS_STATE_TOP;
19952                    break;
19953            }
19954        }
19955
19956        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19957            if (app.hasClientActivities) {
19958                // This is a cached process, but with client activities.  Mark it so.
19959                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19960                app.adjType = "cch-client-act";
19961            } else if (app.treatLikeActivity) {
19962                // This is a cached process, but somebody wants us to treat it like it has
19963                // an activity, okay!
19964                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19965                app.adjType = "cch-as-act";
19966            }
19967        }
19968
19969        if (adj == ProcessList.SERVICE_ADJ) {
19970            if (doingAll) {
19971                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19972                mNewNumServiceProcs++;
19973                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19974                if (!app.serviceb) {
19975                    // This service isn't far enough down on the LRU list to
19976                    // normally be a B service, but if we are low on RAM and it
19977                    // is large we want to force it down since we would prefer to
19978                    // keep launcher over it.
19979                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19980                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19981                        app.serviceHighRam = true;
19982                        app.serviceb = true;
19983                        //Slog.i(TAG, "ADJ " + app + " high ram!");
19984                    } else {
19985                        mNewNumAServiceProcs++;
19986                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
19987                    }
19988                } else {
19989                    app.serviceHighRam = false;
19990                }
19991            }
19992            if (app.serviceb) {
19993                adj = ProcessList.SERVICE_B_ADJ;
19994            }
19995        }
19996
19997        app.curRawAdj = adj;
19998
19999        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
20000        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
20001        if (adj > app.maxAdj) {
20002            adj = app.maxAdj;
20003            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
20004                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20005            }
20006        }
20007
20008        // Do final modification to adj.  Everything we do between here and applying
20009        // the final setAdj must be done in this function, because we will also use
20010        // it when computing the final cached adj later.  Note that we don't need to
20011        // worry about this for max adj above, since max adj will always be used to
20012        // keep it out of the cached vaues.
20013        app.curAdj = app.modifyRawOomAdj(adj);
20014        app.curSchedGroup = schedGroup;
20015        app.curProcState = procState;
20016        app.foregroundActivities = foregroundActivities;
20017
20018        return app.curRawAdj;
20019    }
20020
20021    /**
20022     * Record new PSS sample for a process.
20023     */
20024    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
20025            long now) {
20026        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
20027                swapPss * 1024);
20028        proc.lastPssTime = now;
20029        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
20030        if (DEBUG_PSS) Slog.d(TAG_PSS,
20031                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
20032                + " state=" + ProcessList.makeProcStateString(procState));
20033        if (proc.initialIdlePss == 0) {
20034            proc.initialIdlePss = pss;
20035        }
20036        proc.lastPss = pss;
20037        proc.lastSwapPss = swapPss;
20038        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
20039            proc.lastCachedPss = pss;
20040            proc.lastCachedSwapPss = swapPss;
20041        }
20042
20043        final SparseArray<Pair<Long, String>> watchUids
20044                = mMemWatchProcesses.getMap().get(proc.processName);
20045        Long check = null;
20046        if (watchUids != null) {
20047            Pair<Long, String> val = watchUids.get(proc.uid);
20048            if (val == null) {
20049                val = watchUids.get(0);
20050            }
20051            if (val != null) {
20052                check = val.first;
20053            }
20054        }
20055        if (check != null) {
20056            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
20057                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20058                if (!isDebuggable) {
20059                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
20060                        isDebuggable = true;
20061                    }
20062                }
20063                if (isDebuggable) {
20064                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
20065                    final ProcessRecord myProc = proc;
20066                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
20067                    mMemWatchDumpProcName = proc.processName;
20068                    mMemWatchDumpFile = heapdumpFile.toString();
20069                    mMemWatchDumpPid = proc.pid;
20070                    mMemWatchDumpUid = proc.uid;
20071                    BackgroundThread.getHandler().post(new Runnable() {
20072                        @Override
20073                        public void run() {
20074                            revokeUriPermission(ActivityThread.currentActivityThread()
20075                                            .getApplicationThread(),
20076                                    DumpHeapActivity.JAVA_URI,
20077                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
20078                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
20079                                    UserHandle.myUserId());
20080                            ParcelFileDescriptor fd = null;
20081                            try {
20082                                heapdumpFile.delete();
20083                                fd = ParcelFileDescriptor.open(heapdumpFile,
20084                                        ParcelFileDescriptor.MODE_CREATE |
20085                                                ParcelFileDescriptor.MODE_TRUNCATE |
20086                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
20087                                                ParcelFileDescriptor.MODE_APPEND);
20088                                IApplicationThread thread = myProc.thread;
20089                                if (thread != null) {
20090                                    try {
20091                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
20092                                                "Requesting dump heap from "
20093                                                + myProc + " to " + heapdumpFile);
20094                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
20095                                    } catch (RemoteException e) {
20096                                    }
20097                                }
20098                            } catch (FileNotFoundException e) {
20099                                e.printStackTrace();
20100                            } finally {
20101                                if (fd != null) {
20102                                    try {
20103                                        fd.close();
20104                                    } catch (IOException e) {
20105                                    }
20106                                }
20107                            }
20108                        }
20109                    });
20110                } else {
20111                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
20112                            + ", but debugging not enabled");
20113                }
20114            }
20115        }
20116    }
20117
20118    /**
20119     * Schedule PSS collection of a process.
20120     */
20121    void requestPssLocked(ProcessRecord proc, int procState) {
20122        if (mPendingPssProcesses.contains(proc)) {
20123            return;
20124        }
20125        if (mPendingPssProcesses.size() == 0) {
20126            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
20127        }
20128        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
20129        proc.pssProcState = procState;
20130        mPendingPssProcesses.add(proc);
20131    }
20132
20133    /**
20134     * Schedule PSS collection of all processes.
20135     */
20136    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
20137        if (!always) {
20138            if (now < (mLastFullPssTime +
20139                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
20140                return;
20141            }
20142        }
20143        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
20144        mLastFullPssTime = now;
20145        mFullPssPending = true;
20146        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
20147        mPendingPssProcesses.clear();
20148        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20149            ProcessRecord app = mLruProcesses.get(i);
20150            if (app.thread == null
20151                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
20152                continue;
20153            }
20154            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
20155                app.pssProcState = app.setProcState;
20156                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20157                        mTestPssMode, isSleepingLocked(), now);
20158                mPendingPssProcesses.add(app);
20159            }
20160        }
20161        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
20162    }
20163
20164    public void setTestPssMode(boolean enabled) {
20165        synchronized (this) {
20166            mTestPssMode = enabled;
20167            if (enabled) {
20168                // Whenever we enable the mode, we want to take a snapshot all of current
20169                // process mem use.
20170                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
20171            }
20172        }
20173    }
20174
20175    /**
20176     * Ask a given process to GC right now.
20177     */
20178    final void performAppGcLocked(ProcessRecord app) {
20179        try {
20180            app.lastRequestedGc = SystemClock.uptimeMillis();
20181            if (app.thread != null) {
20182                if (app.reportLowMemory) {
20183                    app.reportLowMemory = false;
20184                    app.thread.scheduleLowMemory();
20185                } else {
20186                    app.thread.processInBackground();
20187                }
20188            }
20189        } catch (Exception e) {
20190            // whatever.
20191        }
20192    }
20193
20194    /**
20195     * Returns true if things are idle enough to perform GCs.
20196     */
20197    private final boolean canGcNowLocked() {
20198        boolean processingBroadcasts = false;
20199        for (BroadcastQueue q : mBroadcastQueues) {
20200            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
20201                processingBroadcasts = true;
20202            }
20203        }
20204        return !processingBroadcasts
20205                && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
20206    }
20207
20208    /**
20209     * Perform GCs on all processes that are waiting for it, but only
20210     * if things are idle.
20211     */
20212    final void performAppGcsLocked() {
20213        final int N = mProcessesToGc.size();
20214        if (N <= 0) {
20215            return;
20216        }
20217        if (canGcNowLocked()) {
20218            while (mProcessesToGc.size() > 0) {
20219                ProcessRecord proc = mProcessesToGc.remove(0);
20220                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
20221                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
20222                            <= SystemClock.uptimeMillis()) {
20223                        // To avoid spamming the system, we will GC processes one
20224                        // at a time, waiting a few seconds between each.
20225                        performAppGcLocked(proc);
20226                        scheduleAppGcsLocked();
20227                        return;
20228                    } else {
20229                        // It hasn't been long enough since we last GCed this
20230                        // process...  put it in the list to wait for its time.
20231                        addProcessToGcListLocked(proc);
20232                        break;
20233                    }
20234                }
20235            }
20236
20237            scheduleAppGcsLocked();
20238        }
20239    }
20240
20241    /**
20242     * If all looks good, perform GCs on all processes waiting for them.
20243     */
20244    final void performAppGcsIfAppropriateLocked() {
20245        if (canGcNowLocked()) {
20246            performAppGcsLocked();
20247            return;
20248        }
20249        // Still not idle, wait some more.
20250        scheduleAppGcsLocked();
20251    }
20252
20253    /**
20254     * Schedule the execution of all pending app GCs.
20255     */
20256    final void scheduleAppGcsLocked() {
20257        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
20258
20259        if (mProcessesToGc.size() > 0) {
20260            // Schedule a GC for the time to the next process.
20261            ProcessRecord proc = mProcessesToGc.get(0);
20262            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
20263
20264            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
20265            long now = SystemClock.uptimeMillis();
20266            if (when < (now+GC_TIMEOUT)) {
20267                when = now + GC_TIMEOUT;
20268            }
20269            mHandler.sendMessageAtTime(msg, when);
20270        }
20271    }
20272
20273    /**
20274     * Add a process to the array of processes waiting to be GCed.  Keeps the
20275     * list in sorted order by the last GC time.  The process can't already be
20276     * on the list.
20277     */
20278    final void addProcessToGcListLocked(ProcessRecord proc) {
20279        boolean added = false;
20280        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
20281            if (mProcessesToGc.get(i).lastRequestedGc <
20282                    proc.lastRequestedGc) {
20283                added = true;
20284                mProcessesToGc.add(i+1, proc);
20285                break;
20286            }
20287        }
20288        if (!added) {
20289            mProcessesToGc.add(0, proc);
20290        }
20291    }
20292
20293    /**
20294     * Set up to ask a process to GC itself.  This will either do it
20295     * immediately, or put it on the list of processes to gc the next
20296     * time things are idle.
20297     */
20298    final void scheduleAppGcLocked(ProcessRecord app) {
20299        long now = SystemClock.uptimeMillis();
20300        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
20301            return;
20302        }
20303        if (!mProcessesToGc.contains(app)) {
20304            addProcessToGcListLocked(app);
20305            scheduleAppGcsLocked();
20306        }
20307    }
20308
20309    final void checkExcessivePowerUsageLocked(boolean doKills) {
20310        updateCpuStatsNow();
20311
20312        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20313        boolean doWakeKills = doKills;
20314        boolean doCpuKills = doKills;
20315        if (mLastPowerCheckRealtime == 0) {
20316            doWakeKills = false;
20317        }
20318        if (mLastPowerCheckUptime == 0) {
20319            doCpuKills = false;
20320        }
20321        if (stats.isScreenOn()) {
20322            doWakeKills = false;
20323        }
20324        final long curRealtime = SystemClock.elapsedRealtime();
20325        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
20326        final long curUptime = SystemClock.uptimeMillis();
20327        final long uptimeSince = curUptime - mLastPowerCheckUptime;
20328        mLastPowerCheckRealtime = curRealtime;
20329        mLastPowerCheckUptime = curUptime;
20330        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
20331            doWakeKills = false;
20332        }
20333        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
20334            doCpuKills = false;
20335        }
20336        int i = mLruProcesses.size();
20337        while (i > 0) {
20338            i--;
20339            ProcessRecord app = mLruProcesses.get(i);
20340            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20341                long wtime;
20342                synchronized (stats) {
20343                    wtime = stats.getProcessWakeTime(app.info.uid,
20344                            app.pid, curRealtime);
20345                }
20346                long wtimeUsed = wtime - app.lastWakeTime;
20347                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
20348                if (DEBUG_POWER) {
20349                    StringBuilder sb = new StringBuilder(128);
20350                    sb.append("Wake for ");
20351                    app.toShortString(sb);
20352                    sb.append(": over ");
20353                    TimeUtils.formatDuration(realtimeSince, sb);
20354                    sb.append(" used ");
20355                    TimeUtils.formatDuration(wtimeUsed, sb);
20356                    sb.append(" (");
20357                    sb.append((wtimeUsed*100)/realtimeSince);
20358                    sb.append("%)");
20359                    Slog.i(TAG_POWER, sb.toString());
20360                    sb.setLength(0);
20361                    sb.append("CPU for ");
20362                    app.toShortString(sb);
20363                    sb.append(": over ");
20364                    TimeUtils.formatDuration(uptimeSince, sb);
20365                    sb.append(" used ");
20366                    TimeUtils.formatDuration(cputimeUsed, sb);
20367                    sb.append(" (");
20368                    sb.append((cputimeUsed*100)/uptimeSince);
20369                    sb.append("%)");
20370                    Slog.i(TAG_POWER, sb.toString());
20371                }
20372                // If a process has held a wake lock for more
20373                // than 50% of the time during this period,
20374                // that sounds bad.  Kill!
20375                if (doWakeKills && realtimeSince > 0
20376                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
20377                    synchronized (stats) {
20378                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
20379                                realtimeSince, wtimeUsed);
20380                    }
20381                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
20382                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
20383                } else if (doCpuKills && uptimeSince > 0
20384                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
20385                    synchronized (stats) {
20386                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
20387                                uptimeSince, cputimeUsed);
20388                    }
20389                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
20390                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
20391                } else {
20392                    app.lastWakeTime = wtime;
20393                    app.lastCpuTime = app.curCpuTime;
20394                }
20395            }
20396        }
20397    }
20398
20399    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
20400            long nowElapsed) {
20401        boolean success = true;
20402
20403        if (app.curRawAdj != app.setRawAdj) {
20404            app.setRawAdj = app.curRawAdj;
20405        }
20406
20407        int changes = 0;
20408
20409        if (app.curAdj != app.setAdj) {
20410            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
20411            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20412                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
20413                    + app.adjType);
20414            app.setAdj = app.curAdj;
20415            app.verifiedAdj = ProcessList.INVALID_ADJ;
20416        }
20417
20418        if (app.setSchedGroup != app.curSchedGroup) {
20419            int oldSchedGroup = app.setSchedGroup;
20420            app.setSchedGroup = app.curSchedGroup;
20421            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20422                    "Setting sched group of " + app.processName
20423                    + " to " + app.curSchedGroup);
20424            if (app.waitingToKill != null && app.curReceivers.isEmpty()
20425                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
20426                app.kill(app.waitingToKill, true);
20427                success = false;
20428            } else {
20429                int processGroup;
20430                switch (app.curSchedGroup) {
20431                    case ProcessList.SCHED_GROUP_BACKGROUND:
20432                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
20433                        break;
20434                    case ProcessList.SCHED_GROUP_TOP_APP:
20435                    case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
20436                        processGroup = Process.THREAD_GROUP_TOP_APP;
20437                        break;
20438                    default:
20439                        processGroup = Process.THREAD_GROUP_DEFAULT;
20440                        break;
20441                }
20442                long oldId = Binder.clearCallingIdentity();
20443                try {
20444                    Process.setProcessGroup(app.pid, processGroup);
20445                    if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
20446                        // do nothing if we already switched to RT
20447                        if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
20448                            // Switch VR thread for app to SCHED_FIFO
20449                            if (mInVrMode && app.vrThreadTid != 0) {
20450                                try {
20451                                    Process.setThreadScheduler(app.vrThreadTid,
20452                                        Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20453                                } catch (IllegalArgumentException e) {
20454                                    // thread died, ignore
20455                                }
20456                            }
20457                            if (mUseFifoUiScheduling) {
20458                                // Switch UI pipeline for app to SCHED_FIFO
20459                                app.savedPriority = Process.getThreadPriority(app.pid);
20460                                try {
20461                                    Process.setThreadScheduler(app.pid,
20462                                        Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20463                                } catch (IllegalArgumentException e) {
20464                                    // thread died, ignore
20465                                }
20466                                if (app.renderThreadTid != 0) {
20467                                    try {
20468                                        Process.setThreadScheduler(app.renderThreadTid,
20469                                            Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20470                                    } catch (IllegalArgumentException e) {
20471                                        // thread died, ignore
20472                                    }
20473                                    if (DEBUG_OOM_ADJ) {
20474                                        Slog.d("UI_FIFO", "Set RenderThread (TID " +
20475                                            app.renderThreadTid + ") to FIFO");
20476                                    }
20477                                } else {
20478                                    if (DEBUG_OOM_ADJ) {
20479                                        Slog.d("UI_FIFO", "Not setting RenderThread TID");
20480                                    }
20481                                }
20482                            } else {
20483                                // Boost priority for top app UI and render threads
20484                                Process.setThreadPriority(app.pid, -10);
20485                                if (app.renderThreadTid != 0) {
20486                                    try {
20487                                        Process.setThreadPriority(app.renderThreadTid, -10);
20488                                    } catch (IllegalArgumentException e) {
20489                                        // thread died, ignore
20490                                    }
20491                                }
20492                            }
20493                        }
20494                    } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
20495                               app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
20496                        // Reset VR thread to SCHED_OTHER
20497                        // Safe to do even if we're not in VR mode
20498                        if (app.vrThreadTid != 0) {
20499                            Process.setThreadScheduler(app.vrThreadTid, Process.SCHED_OTHER, 0);
20500                        }
20501                        if (mUseFifoUiScheduling) {
20502                            // Reset UI pipeline to SCHED_OTHER
20503                            Process.setThreadScheduler(app.pid, Process.SCHED_OTHER, 0);
20504                            Process.setThreadPriority(app.pid, app.savedPriority);
20505                            if (app.renderThreadTid != 0) {
20506                                Process.setThreadScheduler(app.renderThreadTid,
20507                                    Process.SCHED_OTHER, 0);
20508                                Process.setThreadPriority(app.renderThreadTid, -4);
20509                            }
20510                        } else {
20511                            // Reset priority for top app UI and render threads
20512                            Process.setThreadPriority(app.pid, 0);
20513                            if (app.renderThreadTid != 0) {
20514                                Process.setThreadPriority(app.renderThreadTid, 0);
20515                            }
20516                        }
20517                    }
20518                } catch (Exception e) {
20519                    Slog.w(TAG, "Failed setting process group of " + app.pid
20520                            + " to " + app.curSchedGroup);
20521                    e.printStackTrace();
20522                } finally {
20523                    Binder.restoreCallingIdentity(oldId);
20524                }
20525            }
20526        }
20527        if (app.repForegroundActivities != app.foregroundActivities) {
20528            app.repForegroundActivities = app.foregroundActivities;
20529            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
20530        }
20531        if (app.repProcState != app.curProcState) {
20532            app.repProcState = app.curProcState;
20533            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
20534            if (app.thread != null) {
20535                try {
20536                    if (false) {
20537                        //RuntimeException h = new RuntimeException("here");
20538                        Slog.i(TAG, "Sending new process state " + app.repProcState
20539                                + " to " + app /*, h*/);
20540                    }
20541                    app.thread.setProcessState(app.repProcState);
20542                } catch (RemoteException e) {
20543                }
20544            }
20545        }
20546        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
20547                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
20548            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
20549                // Experimental code to more aggressively collect pss while
20550                // running test...  the problem is that this tends to collect
20551                // the data right when a process is transitioning between process
20552                // states, which well tend to give noisy data.
20553                long start = SystemClock.uptimeMillis();
20554                long pss = Debug.getPss(app.pid, mTmpLong, null);
20555                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
20556                mPendingPssProcesses.remove(app);
20557                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
20558                        + " to " + app.curProcState + ": "
20559                        + (SystemClock.uptimeMillis()-start) + "ms");
20560            }
20561            app.lastStateTime = now;
20562            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20563                    mTestPssMode, isSleepingLocked(), now);
20564            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
20565                    + ProcessList.makeProcStateString(app.setProcState) + " to "
20566                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
20567                    + (app.nextPssTime-now) + ": " + app);
20568        } else {
20569            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
20570                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
20571                    mTestPssMode)))) {
20572                requestPssLocked(app, app.setProcState);
20573                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
20574                        mTestPssMode, isSleepingLocked(), now);
20575            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
20576                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
20577        }
20578        if (app.setProcState != app.curProcState) {
20579            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20580                    "Proc state change of " + app.processName
20581                            + " to " + app.curProcState);
20582            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
20583            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
20584            if (setImportant && !curImportant) {
20585                // This app is no longer something we consider important enough to allow to
20586                // use arbitrary amounts of battery power.  Note
20587                // its current wake lock time to later know to kill it if
20588                // it is not behaving well.
20589                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20590                synchronized (stats) {
20591                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
20592                            app.pid, nowElapsed);
20593                }
20594                app.lastCpuTime = app.curCpuTime;
20595
20596            }
20597            // Inform UsageStats of important process state change
20598            // Must be called before updating setProcState
20599            maybeUpdateUsageStatsLocked(app, nowElapsed);
20600
20601            app.setProcState = app.curProcState;
20602            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20603                app.notCachedSinceIdle = false;
20604            }
20605            if (!doingAll) {
20606                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
20607            } else {
20608                app.procStateChanged = true;
20609            }
20610        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
20611                > USAGE_STATS_INTERACTION_INTERVAL) {
20612            // For apps that sit around for a long time in the interactive state, we need
20613            // to report this at least once a day so they don't go idle.
20614            maybeUpdateUsageStatsLocked(app, nowElapsed);
20615        }
20616
20617        if (changes != 0) {
20618            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20619                    "Changes in " + app + ": " + changes);
20620            int i = mPendingProcessChanges.size()-1;
20621            ProcessChangeItem item = null;
20622            while (i >= 0) {
20623                item = mPendingProcessChanges.get(i);
20624                if (item.pid == app.pid) {
20625                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20626                            "Re-using existing item: " + item);
20627                    break;
20628                }
20629                i--;
20630            }
20631            if (i < 0) {
20632                // No existing item in pending changes; need a new one.
20633                final int NA = mAvailProcessChanges.size();
20634                if (NA > 0) {
20635                    item = mAvailProcessChanges.remove(NA-1);
20636                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20637                            "Retrieving available item: " + item);
20638                } else {
20639                    item = new ProcessChangeItem();
20640                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20641                            "Allocating new item: " + item);
20642                }
20643                item.changes = 0;
20644                item.pid = app.pid;
20645                item.uid = app.info.uid;
20646                if (mPendingProcessChanges.size() == 0) {
20647                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20648                            "*** Enqueueing dispatch processes changed!");
20649                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
20650                }
20651                mPendingProcessChanges.add(item);
20652            }
20653            item.changes |= changes;
20654            item.processState = app.repProcState;
20655            item.foregroundActivities = app.repForegroundActivities;
20656            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20657                    "Item " + Integer.toHexString(System.identityHashCode(item))
20658                    + " " + app.toShortString() + ": changes=" + item.changes
20659                    + " procState=" + item.processState
20660                    + " foreground=" + item.foregroundActivities
20661                    + " type=" + app.adjType + " source=" + app.adjSource
20662                    + " target=" + app.adjTarget);
20663        }
20664
20665        return success;
20666    }
20667
20668    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
20669        final UidRecord.ChangeItem pendingChange;
20670        if (uidRec == null || uidRec.pendingChange == null) {
20671            if (mPendingUidChanges.size() == 0) {
20672                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20673                        "*** Enqueueing dispatch uid changed!");
20674                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
20675            }
20676            final int NA = mAvailUidChanges.size();
20677            if (NA > 0) {
20678                pendingChange = mAvailUidChanges.remove(NA-1);
20679                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20680                        "Retrieving available item: " + pendingChange);
20681            } else {
20682                pendingChange = new UidRecord.ChangeItem();
20683                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20684                        "Allocating new item: " + pendingChange);
20685            }
20686            if (uidRec != null) {
20687                uidRec.pendingChange = pendingChange;
20688                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
20689                    // If this uid is going away, and we haven't yet reported it is gone,
20690                    // then do so now.
20691                    change = UidRecord.CHANGE_GONE_IDLE;
20692                }
20693            } else if (uid < 0) {
20694                throw new IllegalArgumentException("No UidRecord or uid");
20695            }
20696            pendingChange.uidRecord = uidRec;
20697            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
20698            mPendingUidChanges.add(pendingChange);
20699        } else {
20700            pendingChange = uidRec.pendingChange;
20701            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
20702                change = UidRecord.CHANGE_GONE_IDLE;
20703            }
20704        }
20705        pendingChange.change = change;
20706        pendingChange.processState = uidRec != null
20707                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
20708    }
20709
20710    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
20711            String authority) {
20712        if (app == null) return;
20713        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20714            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
20715            if (userState == null) return;
20716            final long now = SystemClock.elapsedRealtime();
20717            Long lastReported = userState.mProviderLastReportedFg.get(authority);
20718            if (lastReported == null || lastReported < now - 60 * 1000L) {
20719                if (mSystemReady) {
20720                    // Cannot touch the user stats if not system ready
20721                    mUsageStatsService.reportContentProviderUsage(
20722                            authority, providerPkgName, app.userId);
20723                }
20724                userState.mProviderLastReportedFg.put(authority, now);
20725            }
20726        }
20727    }
20728
20729    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
20730        if (DEBUG_USAGE_STATS) {
20731            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
20732                    + "] state changes: old = " + app.setProcState + ", new = "
20733                    + app.curProcState);
20734        }
20735        if (mUsageStatsService == null) {
20736            return;
20737        }
20738        boolean isInteraction;
20739        // To avoid some abuse patterns, we are going to be careful about what we consider
20740        // to be an app interaction.  Being the top activity doesn't count while the display
20741        // is sleeping, nor do short foreground services.
20742        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
20743            isInteraction = true;
20744            app.fgInteractionTime = 0;
20745        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
20746            if (app.fgInteractionTime == 0) {
20747                app.fgInteractionTime = nowElapsed;
20748                isInteraction = false;
20749            } else {
20750                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
20751            }
20752        } else {
20753            // If the app was being forced to the foreground, by say a Toast, then
20754            // no need to treat it as an interaction
20755            isInteraction = app.forcingToForeground == null
20756                    && app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20757            app.fgInteractionTime = 0;
20758        }
20759        if (isInteraction && (!app.reportedInteraction
20760                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
20761            app.interactionEventTime = nowElapsed;
20762            String[] packages = app.getPackageList();
20763            if (packages != null) {
20764                for (int i = 0; i < packages.length; i++) {
20765                    mUsageStatsService.reportEvent(packages[i], app.userId,
20766                            UsageEvents.Event.SYSTEM_INTERACTION);
20767                }
20768            }
20769        }
20770        app.reportedInteraction = isInteraction;
20771        if (!isInteraction) {
20772            app.interactionEventTime = 0;
20773        }
20774    }
20775
20776    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
20777        if (proc.thread != null) {
20778            if (proc.baseProcessTracker != null) {
20779                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
20780            }
20781        }
20782    }
20783
20784    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
20785            ProcessRecord TOP_APP, boolean doingAll, long now) {
20786        if (app.thread == null) {
20787            return false;
20788        }
20789
20790        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
20791
20792        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
20793    }
20794
20795    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
20796            boolean oomAdj) {
20797        if (isForeground != proc.foregroundServices) {
20798            proc.foregroundServices = isForeground;
20799            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
20800                    proc.info.uid);
20801            if (isForeground) {
20802                if (curProcs == null) {
20803                    curProcs = new ArrayList<ProcessRecord>();
20804                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
20805                }
20806                if (!curProcs.contains(proc)) {
20807                    curProcs.add(proc);
20808                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
20809                            proc.info.packageName, proc.info.uid);
20810                }
20811            } else {
20812                if (curProcs != null) {
20813                    if (curProcs.remove(proc)) {
20814                        mBatteryStatsService.noteEvent(
20815                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
20816                                proc.info.packageName, proc.info.uid);
20817                        if (curProcs.size() <= 0) {
20818                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
20819                        }
20820                    }
20821                }
20822            }
20823            if (oomAdj) {
20824                updateOomAdjLocked();
20825            }
20826        }
20827    }
20828
20829    private final ActivityRecord resumedAppLocked() {
20830        ActivityRecord act = mStackSupervisor.resumedAppLocked();
20831        String pkg;
20832        int uid;
20833        if (act != null) {
20834            pkg = act.packageName;
20835            uid = act.info.applicationInfo.uid;
20836        } else {
20837            pkg = null;
20838            uid = -1;
20839        }
20840        // Has the UID or resumed package name changed?
20841        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
20842                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
20843            if (mCurResumedPackage != null) {
20844                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
20845                        mCurResumedPackage, mCurResumedUid);
20846            }
20847            mCurResumedPackage = pkg;
20848            mCurResumedUid = uid;
20849            if (mCurResumedPackage != null) {
20850                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
20851                        mCurResumedPackage, mCurResumedUid);
20852            }
20853        }
20854        return act;
20855    }
20856
20857    final boolean updateOomAdjLocked(ProcessRecord app) {
20858        final ActivityRecord TOP_ACT = resumedAppLocked();
20859        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20860        final boolean wasCached = app.cached;
20861
20862        mAdjSeq++;
20863
20864        // This is the desired cached adjusment we want to tell it to use.
20865        // If our app is currently cached, we know it, and that is it.  Otherwise,
20866        // we don't know it yet, and it needs to now be cached we will then
20867        // need to do a complete oom adj.
20868        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
20869                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
20870        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
20871                SystemClock.uptimeMillis());
20872        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
20873            // Changed to/from cached state, so apps after it in the LRU
20874            // list may also be changed.
20875            updateOomAdjLocked();
20876        }
20877        return success;
20878    }
20879
20880    final void updateOomAdjLocked() {
20881        final ActivityRecord TOP_ACT = resumedAppLocked();
20882        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20883        final long now = SystemClock.uptimeMillis();
20884        final long nowElapsed = SystemClock.elapsedRealtime();
20885        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20886        final int N = mLruProcesses.size();
20887
20888        if (false) {
20889            RuntimeException e = new RuntimeException();
20890            e.fillInStackTrace();
20891            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20892        }
20893
20894        // Reset state in all uid records.
20895        for (int i=mActiveUids.size()-1; i>=0; i--) {
20896            final UidRecord uidRec = mActiveUids.valueAt(i);
20897            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20898                    "Starting update of " + uidRec);
20899            uidRec.reset();
20900        }
20901
20902        mStackSupervisor.rankTaskLayersIfNeeded();
20903
20904        mAdjSeq++;
20905        mNewNumServiceProcs = 0;
20906        mNewNumAServiceProcs = 0;
20907
20908        final int emptyProcessLimit;
20909        final int cachedProcessLimit;
20910        if (mProcessLimit <= 0) {
20911            emptyProcessLimit = cachedProcessLimit = 0;
20912        } else if (mProcessLimit == 1) {
20913            emptyProcessLimit = 1;
20914            cachedProcessLimit = 0;
20915        } else {
20916            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20917            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20918        }
20919
20920        // Let's determine how many processes we have running vs.
20921        // how many slots we have for background processes; we may want
20922        // to put multiple processes in a slot of there are enough of
20923        // them.
20924        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20925                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20926        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20927        if (numEmptyProcs > cachedProcessLimit) {
20928            // If there are more empty processes than our limit on cached
20929            // processes, then use the cached process limit for the factor.
20930            // This ensures that the really old empty processes get pushed
20931            // down to the bottom, so if we are running low on memory we will
20932            // have a better chance at keeping around more cached processes
20933            // instead of a gazillion empty processes.
20934            numEmptyProcs = cachedProcessLimit;
20935        }
20936        int emptyFactor = numEmptyProcs/numSlots;
20937        if (emptyFactor < 1) emptyFactor = 1;
20938        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20939        if (cachedFactor < 1) cachedFactor = 1;
20940        int stepCached = 0;
20941        int stepEmpty = 0;
20942        int numCached = 0;
20943        int numEmpty = 0;
20944        int numTrimming = 0;
20945
20946        mNumNonCachedProcs = 0;
20947        mNumCachedHiddenProcs = 0;
20948
20949        // First update the OOM adjustment for each of the
20950        // application processes based on their current state.
20951        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20952        int nextCachedAdj = curCachedAdj+1;
20953        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20954        int nextEmptyAdj = curEmptyAdj+2;
20955        for (int i=N-1; i>=0; i--) {
20956            ProcessRecord app = mLruProcesses.get(i);
20957            if (!app.killedByAm && app.thread != null) {
20958                app.procStateChanged = false;
20959                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20960
20961                // If we haven't yet assigned the final cached adj
20962                // to the process, do that now.
20963                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20964                    switch (app.curProcState) {
20965                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20966                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20967                            // This process is a cached process holding activities...
20968                            // assign it the next cached value for that type, and then
20969                            // step that cached level.
20970                            app.curRawAdj = curCachedAdj;
20971                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20972                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20973                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20974                                    + ")");
20975                            if (curCachedAdj != nextCachedAdj) {
20976                                stepCached++;
20977                                if (stepCached >= cachedFactor) {
20978                                    stepCached = 0;
20979                                    curCachedAdj = nextCachedAdj;
20980                                    nextCachedAdj += 2;
20981                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20982                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20983                                    }
20984                                }
20985                            }
20986                            break;
20987                        default:
20988                            // For everything else, assign next empty cached process
20989                            // level and bump that up.  Note that this means that
20990                            // long-running services that have dropped down to the
20991                            // cached level will be treated as empty (since their process
20992                            // state is still as a service), which is what we want.
20993                            app.curRawAdj = curEmptyAdj;
20994                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20995                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20996                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20997                                    + ")");
20998                            if (curEmptyAdj != nextEmptyAdj) {
20999                                stepEmpty++;
21000                                if (stepEmpty >= emptyFactor) {
21001                                    stepEmpty = 0;
21002                                    curEmptyAdj = nextEmptyAdj;
21003                                    nextEmptyAdj += 2;
21004                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
21005                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
21006                                    }
21007                                }
21008                            }
21009                            break;
21010                    }
21011                }
21012
21013                applyOomAdjLocked(app, true, now, nowElapsed);
21014
21015                // Count the number of process types.
21016                switch (app.curProcState) {
21017                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
21018                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
21019                        mNumCachedHiddenProcs++;
21020                        numCached++;
21021                        if (numCached > cachedProcessLimit) {
21022                            app.kill("cached #" + numCached, true);
21023                        }
21024                        break;
21025                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
21026                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
21027                                && app.lastActivityTime < oldTime) {
21028                            app.kill("empty for "
21029                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
21030                                    / 1000) + "s", true);
21031                        } else {
21032                            numEmpty++;
21033                            if (numEmpty > emptyProcessLimit) {
21034                                app.kill("empty #" + numEmpty, true);
21035                            }
21036                        }
21037                        break;
21038                    default:
21039                        mNumNonCachedProcs++;
21040                        break;
21041                }
21042
21043                if (app.isolated && app.services.size() <= 0) {
21044                    // If this is an isolated process, and there are no
21045                    // services running in it, then the process is no longer
21046                    // needed.  We agressively kill these because we can by
21047                    // definition not re-use the same process again, and it is
21048                    // good to avoid having whatever code was running in them
21049                    // left sitting around after no longer needed.
21050                    app.kill("isolated not needed", true);
21051                } else {
21052                    // Keeping this process, update its uid.
21053                    final UidRecord uidRec = app.uidRecord;
21054                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
21055                        uidRec.curProcState = app.curProcState;
21056                    }
21057                }
21058
21059                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
21060                        && !app.killedByAm) {
21061                    numTrimming++;
21062                }
21063            }
21064        }
21065
21066        mNumServiceProcs = mNewNumServiceProcs;
21067
21068        // Now determine the memory trimming level of background processes.
21069        // Unfortunately we need to start at the back of the list to do this
21070        // properly.  We only do this if the number of background apps we
21071        // are managing to keep around is less than half the maximum we desire;
21072        // if we are keeping a good number around, we'll let them use whatever
21073        // memory they want.
21074        final int numCachedAndEmpty = numCached + numEmpty;
21075        int memFactor;
21076        if (numCached <= ProcessList.TRIM_CACHED_APPS
21077                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
21078            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
21079                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
21080            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
21081                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
21082            } else {
21083                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
21084            }
21085        } else {
21086            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
21087        }
21088        // We always allow the memory level to go up (better).  We only allow it to go
21089        // down if we are in a state where that is allowed, *and* the total number of processes
21090        // has gone down since last time.
21091        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
21092                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
21093                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
21094        if (memFactor > mLastMemoryLevel) {
21095            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
21096                memFactor = mLastMemoryLevel;
21097                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
21098            }
21099        }
21100        if (memFactor != mLastMemoryLevel) {
21101            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
21102        }
21103        mLastMemoryLevel = memFactor;
21104        mLastNumProcesses = mLruProcesses.size();
21105        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
21106        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
21107        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
21108            if (mLowRamStartTime == 0) {
21109                mLowRamStartTime = now;
21110            }
21111            int step = 0;
21112            int fgTrimLevel;
21113            switch (memFactor) {
21114                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
21115                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
21116                    break;
21117                case ProcessStats.ADJ_MEM_FACTOR_LOW:
21118                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
21119                    break;
21120                default:
21121                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
21122                    break;
21123            }
21124            int factor = numTrimming/3;
21125            int minFactor = 2;
21126            if (mHomeProcess != null) minFactor++;
21127            if (mPreviousProcess != null) minFactor++;
21128            if (factor < minFactor) factor = minFactor;
21129            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
21130            for (int i=N-1; i>=0; i--) {
21131                ProcessRecord app = mLruProcesses.get(i);
21132                if (allChanged || app.procStateChanged) {
21133                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
21134                    app.procStateChanged = false;
21135                }
21136                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
21137                        && !app.killedByAm) {
21138                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
21139                        try {
21140                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21141                                    "Trimming memory of " + app.processName + " to " + curLevel);
21142                            app.thread.scheduleTrimMemory(curLevel);
21143                        } catch (RemoteException e) {
21144                        }
21145                        if (false) {
21146                            // For now we won't do this; our memory trimming seems
21147                            // to be good enough at this point that destroying
21148                            // activities causes more harm than good.
21149                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
21150                                    && app != mHomeProcess && app != mPreviousProcess) {
21151                                // Need to do this on its own message because the stack may not
21152                                // be in a consistent state at this point.
21153                                // For these apps we will also finish their activities
21154                                // to help them free memory.
21155                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
21156                            }
21157                        }
21158                    }
21159                    app.trimMemoryLevel = curLevel;
21160                    step++;
21161                    if (step >= factor) {
21162                        step = 0;
21163                        switch (curLevel) {
21164                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
21165                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
21166                                break;
21167                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
21168                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
21169                                break;
21170                        }
21171                    }
21172                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
21173                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
21174                            && app.thread != null) {
21175                        try {
21176                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21177                                    "Trimming memory of heavy-weight " + app.processName
21178                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
21179                            app.thread.scheduleTrimMemory(
21180                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
21181                        } catch (RemoteException e) {
21182                        }
21183                    }
21184                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
21185                } else {
21186                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21187                            || app.systemNoUi) && app.pendingUiClean) {
21188                        // If this application is now in the background and it
21189                        // had done UI, then give it the special trim level to
21190                        // have it free UI resources.
21191                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
21192                        if (app.trimMemoryLevel < level && app.thread != null) {
21193                            try {
21194                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21195                                        "Trimming memory of bg-ui " + app.processName
21196                                        + " to " + level);
21197                                app.thread.scheduleTrimMemory(level);
21198                            } catch (RemoteException e) {
21199                            }
21200                        }
21201                        app.pendingUiClean = false;
21202                    }
21203                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
21204                        try {
21205                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21206                                    "Trimming memory of fg " + app.processName
21207                                    + " to " + fgTrimLevel);
21208                            app.thread.scheduleTrimMemory(fgTrimLevel);
21209                        } catch (RemoteException e) {
21210                        }
21211                    }
21212                    app.trimMemoryLevel = fgTrimLevel;
21213                }
21214            }
21215        } else {
21216            if (mLowRamStartTime != 0) {
21217                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
21218                mLowRamStartTime = 0;
21219            }
21220            for (int i=N-1; i>=0; i--) {
21221                ProcessRecord app = mLruProcesses.get(i);
21222                if (allChanged || app.procStateChanged) {
21223                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
21224                    app.procStateChanged = false;
21225                }
21226                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21227                        || app.systemNoUi) && app.pendingUiClean) {
21228                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
21229                            && app.thread != null) {
21230                        try {
21231                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21232                                    "Trimming memory of ui hidden " + app.processName
21233                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
21234                            app.thread.scheduleTrimMemory(
21235                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
21236                        } catch (RemoteException e) {
21237                        }
21238                    }
21239                    app.pendingUiClean = false;
21240                }
21241                app.trimMemoryLevel = 0;
21242            }
21243        }
21244
21245        if (mAlwaysFinishActivities) {
21246            // Need to do this on its own message because the stack may not
21247            // be in a consistent state at this point.
21248            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
21249        }
21250
21251        if (allChanged) {
21252            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
21253        }
21254
21255        // Update from any uid changes.
21256        for (int i=mActiveUids.size()-1; i>=0; i--) {
21257            final UidRecord uidRec = mActiveUids.valueAt(i);
21258            int uidChange = UidRecord.CHANGE_PROCSTATE;
21259            if (uidRec.setProcState != uidRec.curProcState) {
21260                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21261                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
21262                        + " to " + uidRec.curProcState);
21263                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
21264                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
21265                        uidRec.lastBackgroundTime = nowElapsed;
21266                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
21267                            // Note: the background settle time is in elapsed realtime, while
21268                            // the handler time base is uptime.  All this means is that we may
21269                            // stop background uids later than we had intended, but that only
21270                            // happens because the device was sleeping so we are okay anyway.
21271                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
21272                        }
21273                    }
21274                } else {
21275                    if (uidRec.idle) {
21276                        uidChange = UidRecord.CHANGE_ACTIVE;
21277                        uidRec.idle = false;
21278                    }
21279                    uidRec.lastBackgroundTime = 0;
21280                }
21281                uidRec.setProcState = uidRec.curProcState;
21282                enqueueUidChangeLocked(uidRec, -1, uidChange);
21283                noteUidProcessState(uidRec.uid, uidRec.curProcState);
21284            }
21285        }
21286
21287        if (mProcessStats.shouldWriteNowLocked(now)) {
21288            mHandler.post(new Runnable() {
21289                @Override public void run() {
21290                    synchronized (ActivityManagerService.this) {
21291                        mProcessStats.writeStateAsyncLocked();
21292                    }
21293                }
21294            });
21295        }
21296
21297        if (DEBUG_OOM_ADJ) {
21298            final long duration = SystemClock.uptimeMillis() - now;
21299            if (false) {
21300                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
21301                        new RuntimeException("here").fillInStackTrace());
21302            } else {
21303                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
21304            }
21305        }
21306    }
21307
21308    final void idleUids() {
21309        synchronized (this) {
21310            final long nowElapsed = SystemClock.elapsedRealtime();
21311            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
21312            long nextTime = 0;
21313            for (int i=mActiveUids.size()-1; i>=0; i--) {
21314                final UidRecord uidRec = mActiveUids.valueAt(i);
21315                final long bgTime = uidRec.lastBackgroundTime;
21316                if (bgTime > 0 && !uidRec.idle) {
21317                    if (bgTime <= maxBgTime) {
21318                        uidRec.idle = true;
21319                        doStopUidLocked(uidRec.uid, uidRec);
21320                    } else {
21321                        if (nextTime == 0 || nextTime > bgTime) {
21322                            nextTime = bgTime;
21323                        }
21324                    }
21325                }
21326            }
21327            if (nextTime > 0) {
21328                mHandler.removeMessages(IDLE_UIDS_MSG);
21329                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
21330                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
21331            }
21332        }
21333    }
21334
21335    final void runInBackgroundDisabled(int uid) {
21336        synchronized (this) {
21337            UidRecord uidRec = mActiveUids.get(uid);
21338            if (uidRec != null) {
21339                // This uid is actually running...  should it be considered background now?
21340                if (uidRec.idle) {
21341                    doStopUidLocked(uidRec.uid, uidRec);
21342                }
21343            } else {
21344                // This uid isn't actually running...  still send a report about it being "stopped".
21345                doStopUidLocked(uid, null);
21346            }
21347        }
21348    }
21349
21350    final void doStopUidLocked(int uid, final UidRecord uidRec) {
21351        mServices.stopInBackgroundLocked(uid);
21352        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
21353    }
21354
21355    final void trimApplications() {
21356        synchronized (this) {
21357            int i;
21358
21359            // First remove any unused application processes whose package
21360            // has been removed.
21361            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
21362                final ProcessRecord app = mRemovedProcesses.get(i);
21363                if (app.activities.size() == 0
21364                        && app.curReceivers.isEmpty() && app.services.size() == 0) {
21365                    Slog.i(
21366                        TAG, "Exiting empty application process "
21367                        + app.toShortString() + " ("
21368                        + (app.thread != null ? app.thread.asBinder() : null)
21369                        + ")\n");
21370                    if (app.pid > 0 && app.pid != MY_PID) {
21371                        app.kill("empty", false);
21372                    } else {
21373                        try {
21374                            app.thread.scheduleExit();
21375                        } catch (Exception e) {
21376                            // Ignore exceptions.
21377                        }
21378                    }
21379                    cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
21380                    mRemovedProcesses.remove(i);
21381
21382                    if (app.persistent) {
21383                        addAppLocked(app.info, false, null /* ABI override */);
21384                    }
21385                }
21386            }
21387
21388            // Now update the oom adj for all processes.
21389            updateOomAdjLocked();
21390        }
21391    }
21392
21393    /** This method sends the specified signal to each of the persistent apps */
21394    public void signalPersistentProcesses(int sig) throws RemoteException {
21395        if (sig != Process.SIGNAL_USR1) {
21396            throw new SecurityException("Only SIGNAL_USR1 is allowed");
21397        }
21398
21399        synchronized (this) {
21400            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
21401                    != PackageManager.PERMISSION_GRANTED) {
21402                throw new SecurityException("Requires permission "
21403                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
21404            }
21405
21406            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
21407                ProcessRecord r = mLruProcesses.get(i);
21408                if (r.thread != null && r.persistent) {
21409                    Process.sendSignal(r.pid, sig);
21410                }
21411            }
21412        }
21413    }
21414
21415    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
21416        if (proc == null || proc == mProfileProc) {
21417            proc = mProfileProc;
21418            profileType = mProfileType;
21419            clearProfilerLocked();
21420        }
21421        if (proc == null) {
21422            return;
21423        }
21424        try {
21425            proc.thread.profilerControl(false, null, profileType);
21426        } catch (RemoteException e) {
21427            throw new IllegalStateException("Process disappeared");
21428        }
21429    }
21430
21431    private void clearProfilerLocked() {
21432        if (mProfileFd != null) {
21433            try {
21434                mProfileFd.close();
21435            } catch (IOException e) {
21436            }
21437        }
21438        mProfileApp = null;
21439        mProfileProc = null;
21440        mProfileFile = null;
21441        mProfileType = 0;
21442        mAutoStopProfiler = false;
21443        mSamplingInterval = 0;
21444    }
21445
21446    public boolean profileControl(String process, int userId, boolean start,
21447            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
21448
21449        try {
21450            synchronized (this) {
21451                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21452                // its own permission.
21453                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21454                        != PackageManager.PERMISSION_GRANTED) {
21455                    throw new SecurityException("Requires permission "
21456                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21457                }
21458
21459                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
21460                    throw new IllegalArgumentException("null profile info or fd");
21461                }
21462
21463                ProcessRecord proc = null;
21464                if (process != null) {
21465                    proc = findProcessLocked(process, userId, "profileControl");
21466                }
21467
21468                if (start && (proc == null || proc.thread == null)) {
21469                    throw new IllegalArgumentException("Unknown process: " + process);
21470                }
21471
21472                if (start) {
21473                    stopProfilerLocked(null, 0);
21474                    setProfileApp(proc.info, proc.processName, profilerInfo);
21475                    mProfileProc = proc;
21476                    mProfileType = profileType;
21477                    ParcelFileDescriptor fd = profilerInfo.profileFd;
21478                    try {
21479                        fd = fd.dup();
21480                    } catch (IOException e) {
21481                        fd = null;
21482                    }
21483                    profilerInfo.profileFd = fd;
21484                    proc.thread.profilerControl(start, profilerInfo, profileType);
21485                    fd = null;
21486                    mProfileFd = null;
21487                } else {
21488                    stopProfilerLocked(proc, profileType);
21489                    if (profilerInfo != null && profilerInfo.profileFd != null) {
21490                        try {
21491                            profilerInfo.profileFd.close();
21492                        } catch (IOException e) {
21493                        }
21494                    }
21495                }
21496
21497                return true;
21498            }
21499        } catch (RemoteException e) {
21500            throw new IllegalStateException("Process disappeared");
21501        } finally {
21502            if (profilerInfo != null && profilerInfo.profileFd != null) {
21503                try {
21504                    profilerInfo.profileFd.close();
21505                } catch (IOException e) {
21506                }
21507            }
21508        }
21509    }
21510
21511    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
21512        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
21513                userId, true, ALLOW_FULL_ONLY, callName, null);
21514        ProcessRecord proc = null;
21515        try {
21516            int pid = Integer.parseInt(process);
21517            synchronized (mPidsSelfLocked) {
21518                proc = mPidsSelfLocked.get(pid);
21519            }
21520        } catch (NumberFormatException e) {
21521        }
21522
21523        if (proc == null) {
21524            ArrayMap<String, SparseArray<ProcessRecord>> all
21525                    = mProcessNames.getMap();
21526            SparseArray<ProcessRecord> procs = all.get(process);
21527            if (procs != null && procs.size() > 0) {
21528                proc = procs.valueAt(0);
21529                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
21530                    for (int i=1; i<procs.size(); i++) {
21531                        ProcessRecord thisProc = procs.valueAt(i);
21532                        if (thisProc.userId == userId) {
21533                            proc = thisProc;
21534                            break;
21535                        }
21536                    }
21537                }
21538            }
21539        }
21540
21541        return proc;
21542    }
21543
21544    public boolean dumpHeap(String process, int userId, boolean managed,
21545            String path, ParcelFileDescriptor fd) throws RemoteException {
21546
21547        try {
21548            synchronized (this) {
21549                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21550                // its own permission (same as profileControl).
21551                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21552                        != PackageManager.PERMISSION_GRANTED) {
21553                    throw new SecurityException("Requires permission "
21554                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21555                }
21556
21557                if (fd == null) {
21558                    throw new IllegalArgumentException("null fd");
21559                }
21560
21561                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
21562                if (proc == null || proc.thread == null) {
21563                    throw new IllegalArgumentException("Unknown process: " + process);
21564                }
21565
21566                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21567                if (!isDebuggable) {
21568                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21569                        throw new SecurityException("Process not debuggable: " + proc);
21570                    }
21571                }
21572
21573                proc.thread.dumpHeap(managed, path, fd);
21574                fd = null;
21575                return true;
21576            }
21577        } catch (RemoteException e) {
21578            throw new IllegalStateException("Process disappeared");
21579        } finally {
21580            if (fd != null) {
21581                try {
21582                    fd.close();
21583                } catch (IOException e) {
21584                }
21585            }
21586        }
21587    }
21588
21589    @Override
21590    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
21591            String reportPackage) {
21592        if (processName != null) {
21593            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
21594                    "setDumpHeapDebugLimit()");
21595        } else {
21596            synchronized (mPidsSelfLocked) {
21597                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
21598                if (proc == null) {
21599                    throw new SecurityException("No process found for calling pid "
21600                            + Binder.getCallingPid());
21601                }
21602                if (!Build.IS_DEBUGGABLE
21603                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21604                    throw new SecurityException("Not running a debuggable build");
21605                }
21606                processName = proc.processName;
21607                uid = proc.uid;
21608                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
21609                    throw new SecurityException("Package " + reportPackage + " is not running in "
21610                            + proc);
21611                }
21612            }
21613        }
21614        synchronized (this) {
21615            if (maxMemSize > 0) {
21616                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
21617            } else {
21618                if (uid != 0) {
21619                    mMemWatchProcesses.remove(processName, uid);
21620                } else {
21621                    mMemWatchProcesses.getMap().remove(processName);
21622                }
21623            }
21624        }
21625    }
21626
21627    @Override
21628    public void dumpHeapFinished(String path) {
21629        synchronized (this) {
21630            if (Binder.getCallingPid() != mMemWatchDumpPid) {
21631                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
21632                        + " does not match last pid " + mMemWatchDumpPid);
21633                return;
21634            }
21635            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
21636                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
21637                        + " does not match last path " + mMemWatchDumpFile);
21638                return;
21639            }
21640            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
21641            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
21642        }
21643    }
21644
21645    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
21646    public void monitor() {
21647        synchronized (this) { }
21648    }
21649
21650    void onCoreSettingsChange(Bundle settings) {
21651        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21652            ProcessRecord processRecord = mLruProcesses.get(i);
21653            try {
21654                if (processRecord.thread != null) {
21655                    processRecord.thread.setCoreSettings(settings);
21656                }
21657            } catch (RemoteException re) {
21658                /* ignore */
21659            }
21660        }
21661    }
21662
21663    // Multi-user methods
21664
21665    /**
21666     * Start user, if its not already running, but don't bring it to foreground.
21667     */
21668    @Override
21669    public boolean startUserInBackground(final int userId) {
21670        return mUserController.startUser(userId, /* foreground */ false);
21671    }
21672
21673    @Override
21674    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
21675        return mUserController.unlockUser(userId, token, secret, listener);
21676    }
21677
21678    @Override
21679    public boolean switchUser(final int targetUserId) {
21680        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
21681        UserInfo currentUserInfo;
21682        UserInfo targetUserInfo;
21683        synchronized (this) {
21684            int currentUserId = mUserController.getCurrentUserIdLocked();
21685            currentUserInfo = mUserController.getUserInfo(currentUserId);
21686            targetUserInfo = mUserController.getUserInfo(targetUserId);
21687            if (targetUserInfo == null) {
21688                Slog.w(TAG, "No user info for user #" + targetUserId);
21689                return false;
21690            }
21691            if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
21692                Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
21693                        + " when device is in demo mode");
21694                return false;
21695            }
21696            if (!targetUserInfo.supportsSwitchTo()) {
21697                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
21698                return false;
21699            }
21700            if (targetUserInfo.isManagedProfile()) {
21701                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
21702                return false;
21703            }
21704            mUserController.setTargetUserIdLocked(targetUserId);
21705        }
21706        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
21707        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
21708        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
21709        return true;
21710    }
21711
21712    void scheduleStartProfilesLocked() {
21713        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
21714            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
21715                    DateUtils.SECOND_IN_MILLIS);
21716        }
21717    }
21718
21719    @Override
21720    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
21721        return mUserController.stopUser(userId, force, callback);
21722    }
21723
21724    @Override
21725    public UserInfo getCurrentUser() {
21726        return mUserController.getCurrentUser();
21727    }
21728
21729    @Override
21730    public boolean isUserRunning(int userId, int flags) {
21731        if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
21732                && checkCallingPermission(INTERACT_ACROSS_USERS)
21733                    != PackageManager.PERMISSION_GRANTED) {
21734            String msg = "Permission Denial: isUserRunning() from pid="
21735                    + Binder.getCallingPid()
21736                    + ", uid=" + Binder.getCallingUid()
21737                    + " requires " + INTERACT_ACROSS_USERS;
21738            Slog.w(TAG, msg);
21739            throw new SecurityException(msg);
21740        }
21741        synchronized (this) {
21742            return mUserController.isUserRunningLocked(userId, flags);
21743        }
21744    }
21745
21746    @Override
21747    public int[] getRunningUserIds() {
21748        if (checkCallingPermission(INTERACT_ACROSS_USERS)
21749                != PackageManager.PERMISSION_GRANTED) {
21750            String msg = "Permission Denial: isUserRunning() from pid="
21751                    + Binder.getCallingPid()
21752                    + ", uid=" + Binder.getCallingUid()
21753                    + " requires " + INTERACT_ACROSS_USERS;
21754            Slog.w(TAG, msg);
21755            throw new SecurityException(msg);
21756        }
21757        synchronized (this) {
21758            return mUserController.getStartedUserArrayLocked();
21759        }
21760    }
21761
21762    @Override
21763    public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
21764        mUserController.registerUserSwitchObserver(observer, name);
21765    }
21766
21767    @Override
21768    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
21769        mUserController.unregisterUserSwitchObserver(observer);
21770    }
21771
21772    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
21773        if (info == null) return null;
21774        ApplicationInfo newInfo = new ApplicationInfo(info);
21775        newInfo.initForUser(userId);
21776        return newInfo;
21777    }
21778
21779    public boolean isUserStopped(int userId) {
21780        synchronized (this) {
21781            return mUserController.getStartedUserStateLocked(userId) == null;
21782        }
21783    }
21784
21785    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
21786        if (aInfo == null
21787                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
21788            return aInfo;
21789        }
21790
21791        ActivityInfo info = new ActivityInfo(aInfo);
21792        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
21793        return info;
21794    }
21795
21796    private boolean processSanityChecksLocked(ProcessRecord process) {
21797        if (process == null || process.thread == null) {
21798            return false;
21799        }
21800
21801        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21802        if (!isDebuggable) {
21803            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21804                return false;
21805            }
21806        }
21807
21808        return true;
21809    }
21810
21811    public boolean startBinderTracking() throws RemoteException {
21812        synchronized (this) {
21813            mBinderTransactionTrackingEnabled = true;
21814            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21815            // permission (same as profileControl).
21816            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21817                    != PackageManager.PERMISSION_GRANTED) {
21818                throw new SecurityException("Requires permission "
21819                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21820            }
21821
21822            for (int i = 0; i < mLruProcesses.size(); i++) {
21823                ProcessRecord process = mLruProcesses.get(i);
21824                if (!processSanityChecksLocked(process)) {
21825                    continue;
21826                }
21827                try {
21828                    process.thread.startBinderTracking();
21829                } catch (RemoteException e) {
21830                    Log.v(TAG, "Process disappared");
21831                }
21832            }
21833            return true;
21834        }
21835    }
21836
21837    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
21838        try {
21839            synchronized (this) {
21840                mBinderTransactionTrackingEnabled = false;
21841                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21842                // permission (same as profileControl).
21843                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21844                        != PackageManager.PERMISSION_GRANTED) {
21845                    throw new SecurityException("Requires permission "
21846                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21847                }
21848
21849                if (fd == null) {
21850                    throw new IllegalArgumentException("null fd");
21851                }
21852
21853                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
21854                pw.println("Binder transaction traces for all processes.\n");
21855                for (ProcessRecord process : mLruProcesses) {
21856                    if (!processSanityChecksLocked(process)) {
21857                        continue;
21858                    }
21859
21860                    pw.println("Traces for process: " + process.processName);
21861                    pw.flush();
21862                    try {
21863                        TransferPipe tp = new TransferPipe();
21864                        try {
21865                            process.thread.stopBinderTrackingAndDump(
21866                                    tp.getWriteFd().getFileDescriptor());
21867                            tp.go(fd.getFileDescriptor());
21868                        } finally {
21869                            tp.kill();
21870                        }
21871                    } catch (IOException e) {
21872                        pw.println("Failure while dumping IPC traces from " + process +
21873                                ".  Exception: " + e);
21874                        pw.flush();
21875                    } catch (RemoteException e) {
21876                        pw.println("Got a RemoteException while dumping IPC traces from " +
21877                                process + ".  Exception: " + e);
21878                        pw.flush();
21879                    }
21880                }
21881                fd = null;
21882                return true;
21883            }
21884        } finally {
21885            if (fd != null) {
21886                try {
21887                    fd.close();
21888                } catch (IOException e) {
21889                }
21890            }
21891        }
21892    }
21893
21894    private final class LocalService extends ActivityManagerInternal {
21895        @Override
21896        public void onWakefulnessChanged(int wakefulness) {
21897            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21898        }
21899
21900        @Override
21901        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21902                String processName, String abiOverride, int uid, Runnable crashHandler) {
21903            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21904                    processName, abiOverride, uid, crashHandler);
21905        }
21906
21907        @Override
21908        public SleepToken acquireSleepToken(String tag) {
21909            Preconditions.checkNotNull(tag);
21910
21911            ComponentName requestedVrService = null;
21912            ComponentName callingVrActivity = null;
21913            int userId = -1;
21914            synchronized (ActivityManagerService.this) {
21915                if (mFocusedActivity != null) {
21916                    requestedVrService = mFocusedActivity.requestedVrComponent;
21917                    callingVrActivity = mFocusedActivity.info.getComponentName();
21918                    userId = mFocusedActivity.userId;
21919                }
21920            }
21921
21922            if (requestedVrService != null) {
21923                applyVrMode(false, requestedVrService, userId, callingVrActivity, true);
21924            }
21925
21926            synchronized (ActivityManagerService.this) {
21927                SleepTokenImpl token = new SleepTokenImpl(tag);
21928                mSleepTokens.add(token);
21929                updateSleepIfNeededLocked();
21930                return token;
21931            }
21932        }
21933
21934        @Override
21935        public ComponentName getHomeActivityForUser(int userId) {
21936            synchronized (ActivityManagerService.this) {
21937                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21938                return homeActivity == null ? null : homeActivity.realActivity;
21939            }
21940        }
21941
21942        @Override
21943        public void onUserRemoved(int userId) {
21944            synchronized (ActivityManagerService.this) {
21945                ActivityManagerService.this.onUserStoppedLocked(userId);
21946            }
21947        }
21948
21949        @Override
21950        public void onLocalVoiceInteractionStarted(IBinder activity,
21951                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
21952            synchronized (ActivityManagerService.this) {
21953                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21954                        voiceSession, voiceInteractor);
21955            }
21956        }
21957
21958        @Override
21959        public void notifyStartingWindowDrawn() {
21960            synchronized (ActivityManagerService.this) {
21961                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
21962            }
21963        }
21964
21965        @Override
21966        public void notifyAppTransitionStarting(int reason) {
21967            synchronized (ActivityManagerService.this) {
21968                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
21969            }
21970        }
21971
21972        @Override
21973        public void notifyAppTransitionFinished() {
21974            synchronized (ActivityManagerService.this) {
21975                mStackSupervisor.notifyAppTransitionDone();
21976            }
21977        }
21978
21979        @Override
21980        public void notifyAppTransitionCancelled() {
21981            synchronized (ActivityManagerService.this) {
21982                mStackSupervisor.notifyAppTransitionDone();
21983            }
21984        }
21985
21986        @Override
21987        public List<IBinder> getTopVisibleActivities() {
21988            synchronized (ActivityManagerService.this) {
21989                return mStackSupervisor.getTopVisibleActivities();
21990            }
21991        }
21992
21993        @Override
21994        public void notifyDockedStackMinimizedChanged(boolean minimized) {
21995            synchronized (ActivityManagerService.this) {
21996                mStackSupervisor.setDockedStackMinimized(minimized);
21997            }
21998        }
21999
22000        @Override
22001        public void killForegroundAppsForUser(int userHandle) {
22002            synchronized (ActivityManagerService.this) {
22003                final ArrayList<ProcessRecord> procs = new ArrayList<>();
22004                final int NP = mProcessNames.getMap().size();
22005                for (int ip = 0; ip < NP; ip++) {
22006                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
22007                    final int NA = apps.size();
22008                    for (int ia = 0; ia < NA; ia++) {
22009                        final ProcessRecord app = apps.valueAt(ia);
22010                        if (app.persistent) {
22011                            // We don't kill persistent processes.
22012                            continue;
22013                        }
22014                        if (app.removed) {
22015                            procs.add(app);
22016                        } else if (app.userId == userHandle && app.foregroundActivities) {
22017                            app.removed = true;
22018                            procs.add(app);
22019                        }
22020                    }
22021                }
22022
22023                final int N = procs.size();
22024                for (int i = 0; i < N; i++) {
22025                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
22026                }
22027            }
22028        }
22029
22030        @Override
22031        public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
22032            if (!(target instanceof PendingIntentRecord)) {
22033                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
22034                return;
22035            }
22036            ((PendingIntentRecord) target).setWhitelistDuration(duration);
22037        }
22038
22039        @Override
22040        public void updatePersistentConfigurationForUser(@NonNull Configuration values,
22041                int userId) {
22042            Preconditions.checkNotNull(values, "Configuration must not be null");
22043            Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
22044            synchronized (ActivityManagerService.this) {
22045                updateConfigurationLocked(values, null, false, true, userId,
22046                        false /* deferResume */);
22047            }
22048        }
22049
22050        @Override
22051        public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
22052                Bundle bOptions) {
22053            Preconditions.checkNotNull(intents, "intents");
22054            final String[] resolvedTypes = new String[intents.length];
22055            for (int i = 0; i < intents.length; i++) {
22056                resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
22057            }
22058
22059            // UID of the package on user userId.
22060            // "= 0" is needed because otherwise catch(RemoteException) would make it look like
22061            // packageUid may not be initialized.
22062            int packageUid = 0;
22063            try {
22064                packageUid = AppGlobals.getPackageManager().getPackageUid(
22065                        packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
22066            } catch (RemoteException e) {
22067                // Shouldn't happen.
22068            }
22069
22070            synchronized (ActivityManagerService.this) {
22071                return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
22072                        /*resultTo*/ null, bOptions, userId);
22073            }
22074        }
22075
22076        @Override
22077        public int getUidProcessState(int uid) {
22078            return getUidState(uid);
22079        }
22080    }
22081
22082    private final class SleepTokenImpl extends SleepToken {
22083        private final String mTag;
22084        private final long mAcquireTime;
22085
22086        public SleepTokenImpl(String tag) {
22087            mTag = tag;
22088            mAcquireTime = SystemClock.uptimeMillis();
22089        }
22090
22091        @Override
22092        public void release() {
22093            synchronized (ActivityManagerService.this) {
22094                if (mSleepTokens.remove(this)) {
22095                    updateSleepIfNeededLocked();
22096                }
22097            }
22098        }
22099
22100        @Override
22101        public String toString() {
22102            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
22103        }
22104    }
22105
22106    /**
22107     * An implementation of IAppTask, that allows an app to manage its own tasks via
22108     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
22109     * only the process that calls getAppTasks() can call the AppTask methods.
22110     */
22111    class AppTaskImpl extends IAppTask.Stub {
22112        private int mTaskId;
22113        private int mCallingUid;
22114
22115        public AppTaskImpl(int taskId, int callingUid) {
22116            mTaskId = taskId;
22117            mCallingUid = callingUid;
22118        }
22119
22120        private void checkCaller() {
22121            if (mCallingUid != Binder.getCallingUid()) {
22122                throw new SecurityException("Caller " + mCallingUid
22123                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
22124            }
22125        }
22126
22127        @Override
22128        public void finishAndRemoveTask() {
22129            checkCaller();
22130
22131            synchronized (ActivityManagerService.this) {
22132                long origId = Binder.clearCallingIdentity();
22133                try {
22134                    // We remove the task from recents to preserve backwards
22135                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
22136                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22137                    }
22138                } finally {
22139                    Binder.restoreCallingIdentity(origId);
22140                }
22141            }
22142        }
22143
22144        @Override
22145        public ActivityManager.RecentTaskInfo getTaskInfo() {
22146            checkCaller();
22147
22148            synchronized (ActivityManagerService.this) {
22149                long origId = Binder.clearCallingIdentity();
22150                try {
22151                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22152                    if (tr == null) {
22153                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22154                    }
22155                    return createRecentTaskInfoFromTaskRecord(tr);
22156                } finally {
22157                    Binder.restoreCallingIdentity(origId);
22158                }
22159            }
22160        }
22161
22162        @Override
22163        public void moveToFront() {
22164            checkCaller();
22165            // Will bring task to front if it already has a root activity.
22166            final long origId = Binder.clearCallingIdentity();
22167            try {
22168                synchronized (this) {
22169                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
22170                }
22171            } finally {
22172                Binder.restoreCallingIdentity(origId);
22173            }
22174        }
22175
22176        @Override
22177        public int startActivity(IBinder whoThread, String callingPackage,
22178                Intent intent, String resolvedType, Bundle bOptions) {
22179            checkCaller();
22180
22181            int callingUser = UserHandle.getCallingUserId();
22182            TaskRecord tr;
22183            IApplicationThread appThread;
22184            synchronized (ActivityManagerService.this) {
22185                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22186                if (tr == null) {
22187                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22188                }
22189                appThread = ApplicationThreadNative.asInterface(whoThread);
22190                if (appThread == null) {
22191                    throw new IllegalArgumentException("Bad app thread " + appThread);
22192                }
22193            }
22194            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
22195                    resolvedType, null, null, null, null, 0, 0, null, null,
22196                    null, bOptions, false, callingUser, null, tr);
22197        }
22198
22199        @Override
22200        public void setExcludeFromRecents(boolean exclude) {
22201            checkCaller();
22202
22203            synchronized (ActivityManagerService.this) {
22204                long origId = Binder.clearCallingIdentity();
22205                try {
22206                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22207                    if (tr == null) {
22208                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22209                    }
22210                    Intent intent = tr.getBaseIntent();
22211                    if (exclude) {
22212                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
22213                    } else {
22214                        intent.setFlags(intent.getFlags()
22215                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
22216                    }
22217                } finally {
22218                    Binder.restoreCallingIdentity(origId);
22219                }
22220            }
22221        }
22222    }
22223
22224    /**
22225     * Kill processes for the user with id userId and that depend on the package named packageName
22226     */
22227    @Override
22228    public void killPackageDependents(String packageName, int userId) {
22229        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
22230        if (packageName == null) {
22231            throw new NullPointerException(
22232                    "Cannot kill the dependents of a package without its name.");
22233        }
22234
22235        long callingId = Binder.clearCallingIdentity();
22236        IPackageManager pm = AppGlobals.getPackageManager();
22237        int pkgUid = -1;
22238        try {
22239            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
22240        } catch (RemoteException e) {
22241        }
22242        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
22243            throw new IllegalArgumentException(
22244                    "Cannot kill dependents of non-existing package " + packageName);
22245        }
22246        try {
22247            synchronized(this) {
22248                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
22249                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
22250                        "dep: " + packageName);
22251            }
22252        } finally {
22253            Binder.restoreCallingIdentity(callingId);
22254        }
22255    }
22256
22257    @Override
22258    public boolean canBypassWorkChallenge(PendingIntent intent) throws RemoteException {
22259        final int userId = intent.getCreatorUserHandle().getIdentifier();
22260        if (!mUserController.isUserRunningLocked(userId, ActivityManager.FLAG_AND_LOCKED)) {
22261            return false;
22262        }
22263        IIntentSender target = intent.getTarget();
22264        if (!(target instanceof PendingIntentRecord)) {
22265            return false;
22266        }
22267        final PendingIntentRecord record = (PendingIntentRecord) target;
22268        final ResolveInfo rInfo = mStackSupervisor.resolveIntent(record.key.requestIntent,
22269                record.key.requestResolvedType, userId, PackageManager.MATCH_DIRECT_BOOT_AWARE);
22270        // For direct boot aware activities, they can be shown without triggering a work challenge
22271        // before the profile user is unlocked.
22272        return rInfo != null && rInfo.activityInfo != null;
22273    }
22274}
22275