ActivityManagerService.java revision 3c6f28aa5968b1edb823495efa15e7358de5261e
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 android.annotation.Nullable;
20import android.app.ActivityManagerInternal.PictureInPictureArguments;
21import android.app.ApplicationThreadConstants;
22import android.app.ContentProviderHolder;
23import android.app.IActivityManager;
24import android.app.RemoteAction;
25import android.app.WaitResult;
26import android.os.IDeviceIdentifiersPolicyService;
27
28import com.android.internal.policy.IKeyguardDismissCallback;
29import com.android.internal.telephony.TelephonyIntents;
30import com.google.android.collect.Lists;
31import com.google.android.collect.Maps;
32import com.android.internal.R;
33import com.android.internal.annotations.GuardedBy;
34import com.android.internal.app.AssistUtils;
35import com.android.internal.app.DumpHeapActivity;
36import com.android.internal.app.IAppOpsCallback;
37import com.android.internal.app.IAppOpsService;
38import com.android.internal.app.IVoiceInteractor;
39import com.android.internal.app.ProcessMap;
40import com.android.internal.app.SystemUserHomeActivity;
41import com.android.internal.app.procstats.ProcessStats;
42import com.android.internal.os.BackgroundThread;
43import com.android.internal.os.BatteryStatsImpl;
44import com.android.internal.os.IResultReceiver;
45import com.android.internal.os.ProcessCpuTracker;
46import com.android.internal.os.TransferPipe;
47import com.android.internal.os.Zygote;
48import com.android.internal.util.ArrayUtils;
49import com.android.internal.util.FastPrintWriter;
50import com.android.internal.util.FastXmlSerializer;
51import com.android.internal.util.MemInfoReader;
52import com.android.internal.util.Preconditions;
53import com.android.server.AppOpsService;
54import com.android.server.AttributeCache;
55import com.android.server.DeviceIdleController;
56import com.android.server.IntentResolver;
57import com.android.server.LocalServices;
58import com.android.server.LockGuard;
59import com.android.server.ServiceThread;
60import com.android.server.SystemService;
61import com.android.server.SystemServiceManager;
62import com.android.server.Watchdog;
63import com.android.server.am.ActivityStack.ActivityState;
64import com.android.server.firewall.IntentFirewall;
65import com.android.server.pm.Installer;
66import com.android.server.pm.Installer.InstallerException;
67import com.android.server.statusbar.StatusBarManagerInternal;
68import com.android.server.vr.VrManagerInternal;
69import com.android.server.wm.WindowManagerService;
70
71import org.xmlpull.v1.XmlPullParser;
72import org.xmlpull.v1.XmlPullParserException;
73import org.xmlpull.v1.XmlSerializer;
74
75import android.Manifest;
76import android.Manifest.permission;
77import android.annotation.NonNull;
78import android.annotation.UserIdInt;
79import android.app.Activity;
80import android.app.ActivityManager;
81import android.app.ActivityManager.RunningTaskInfo;
82import android.app.ActivityManager.StackId;
83import android.app.ActivityManager.StackInfo;
84import android.app.ActivityManager.TaskThumbnailInfo;
85import android.app.ActivityManagerInternal;
86import android.app.ActivityManagerInternal.SleepToken;
87import android.app.ActivityOptions;
88import android.app.ActivityThread;
89import android.app.AlertDialog;
90import android.app.AppGlobals;
91import android.app.AppOpsManager;
92import android.app.ApplicationErrorReport;
93import android.app.BroadcastOptions;
94import android.app.Dialog;
95import android.app.IActivityContainer;
96import android.app.IActivityContainerCallback;
97import android.app.IActivityController;
98import android.app.IAppTask;
99import android.app.IApplicationThread;
100import android.app.IInstrumentationWatcher;
101import android.app.INotificationManager;
102import android.app.IProcessObserver;
103import android.app.IServiceConnection;
104import android.app.IStopUserCallback;
105import android.app.ITaskStackListener;
106import android.app.IUiAutomationConnection;
107import android.app.IUidObserver;
108import android.app.IUserSwitchObserver;
109import android.app.Instrumentation;
110import android.app.Notification;
111import android.app.NotificationManager;
112import android.app.PendingIntent;
113import android.app.ProfilerInfo;
114import android.app.admin.DevicePolicyManager;
115import android.app.assist.AssistContent;
116import android.app.assist.AssistStructure;
117import android.app.backup.IBackupManager;
118import android.app.usage.UsageEvents;
119import android.app.usage.UsageStatsManagerInternal;
120import android.appwidget.AppWidgetManager;
121import android.content.ActivityNotFoundException;
122import android.content.BroadcastReceiver;
123import android.content.ClipData;
124import android.content.ComponentCallbacks2;
125import android.content.ComponentName;
126import android.content.ContentProvider;
127import android.content.ContentResolver;
128import android.content.Context;
129import android.content.DialogInterface;
130import android.content.IContentProvider;
131import android.content.IIntentReceiver;
132import android.content.IIntentSender;
133import android.content.Intent;
134import android.content.IntentFilter;
135import android.content.IntentSender;
136import android.content.pm.ActivityInfo;
137import android.content.pm.ApplicationInfo;
138import android.content.pm.ConfigurationInfo;
139import android.content.pm.IPackageDataObserver;
140import android.content.pm.IPackageManager;
141import android.content.pm.InstrumentationInfo;
142import android.content.pm.PackageInfo;
143import android.content.pm.PackageManager;
144import android.content.pm.PackageManager.NameNotFoundException;
145import android.content.pm.PackageManagerInternal;
146import android.content.pm.ParceledListSlice;
147import android.content.pm.PathPermission;
148import android.content.pm.PermissionInfo;
149import android.content.pm.ProviderInfo;
150import android.content.pm.ResolveInfo;
151import android.content.pm.ServiceInfo;
152import android.content.pm.UserInfo;
153import android.content.res.CompatibilityInfo;
154import android.content.res.Configuration;
155import android.content.res.Resources;
156import android.database.ContentObserver;
157import android.graphics.Bitmap;
158import android.graphics.Point;
159import android.graphics.Rect;
160import android.location.LocationManager;
161import android.net.Proxy;
162import android.net.ProxyInfo;
163import android.net.Uri;
164import android.os.BatteryStats;
165import android.os.Binder;
166import android.os.Build;
167import android.os.Bundle;
168import android.os.Debug;
169import android.os.DropBoxManager;
170import android.os.Environment;
171import android.os.FactoryTest;
172import android.os.FileObserver;
173import android.os.FileUtils;
174import android.os.Handler;
175import android.os.IBinder;
176import android.os.IPermissionController;
177import android.os.IProcessInfoService;
178import android.os.IProgressListener;
179import android.os.LocaleList;
180import android.os.Looper;
181import android.os.Message;
182import android.os.Parcel;
183import android.os.ParcelFileDescriptor;
184import android.os.PersistableBundle;
185import android.os.PowerManager;
186import android.os.PowerManagerInternal;
187import android.os.Process;
188import android.os.RemoteCallbackList;
189import android.os.RemoteException;
190import android.os.ResultReceiver;
191import android.os.ServiceManager;
192import android.os.ShellCallback;
193import android.os.StrictMode;
194import android.os.SystemClock;
195import android.os.SystemProperties;
196import android.os.Trace;
197import android.os.TransactionTooLargeException;
198import android.os.UpdateLock;
199import android.os.UserHandle;
200import android.os.UserManager;
201import android.os.WorkSource;
202import android.os.storage.IStorageManager;
203import android.os.storage.StorageManagerInternal;
204import android.os.storage.StorageManager;
205import android.provider.Downloads;
206import android.provider.Settings;
207import android.service.autofill.AutoFillService;
208import android.service.voice.IVoiceInteractionSession;
209import android.service.voice.VoiceInteractionManagerInternal;
210import android.service.voice.VoiceInteractionSession;
211import android.telecom.TelecomManager;
212import android.text.format.DateUtils;
213import android.text.format.Time;
214import android.text.style.SuggestionSpan;
215import android.util.ArrayMap;
216import android.util.ArraySet;
217import android.util.AtomicFile;
218import android.util.BootTimingsTraceLog;
219import android.util.DebugUtils;
220import android.util.DisplayMetrics;
221import android.util.EventLog;
222import android.util.Log;
223import android.util.Pair;
224import android.util.PrintWriterPrinter;
225import android.util.Slog;
226import android.util.SparseArray;
227import android.util.SparseIntArray;
228import android.util.TimeUtils;
229import android.util.Xml;
230import android.view.Gravity;
231import android.view.LayoutInflater;
232import android.view.View;
233import android.view.WindowManager;
234
235import java.io.File;
236import java.io.FileDescriptor;
237import java.io.FileInputStream;
238import java.io.FileNotFoundException;
239import java.io.FileOutputStream;
240import java.io.IOException;
241import java.io.InputStreamReader;
242import java.io.PrintWriter;
243import java.io.StringWriter;
244import java.lang.ref.WeakReference;
245import java.nio.charset.StandardCharsets;
246import java.util.ArrayList;
247import java.util.Arrays;
248import java.util.Collections;
249import java.util.Comparator;
250import java.util.HashMap;
251import java.util.HashSet;
252import java.util.Iterator;
253import java.util.List;
254import java.util.Locale;
255import java.util.Map;
256import java.util.Objects;
257import java.util.Set;
258import java.util.concurrent.atomic.AtomicBoolean;
259import java.util.concurrent.atomic.AtomicLong;
260import java.util.concurrent.CountDownLatch;
261
262import dalvik.system.VMRuntime;
263
264import libcore.io.IoUtils;
265import libcore.util.EmptyArray;
266
267import static android.Manifest.permission.CHANGE_CONFIGURATION;
268import static android.Manifest.permission.INTERACT_ACROSS_USERS;
269import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
270import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
271import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
272import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
273import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
274import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
275import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
276import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
277import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
278import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
279import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
280import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
281import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
282import static android.content.pm.PackageManager.GET_PROVIDERS;
283import static android.content.pm.PackageManager.MATCH_ANY_USER;
284import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
285import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
286import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
287import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
288import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
289import static android.content.pm.PackageManager.PERMISSION_GRANTED;
290import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
291import static android.os.Build.VERSION_CODES.N;
292import static android.os.Process.PROC_CHAR;
293import static android.os.Process.PROC_OUT_LONG;
294import static android.os.Process.PROC_PARENS;
295import static android.os.Process.PROC_SPACE_TERM;
296import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
297import static android.provider.Settings.Global.DEBUG_APP;
298import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
299import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
300import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
301import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
302import static android.provider.Settings.System.FONT_SCALE;
303import static android.view.Display.DEFAULT_DISPLAY;
304
305import static com.android.internal.util.XmlUtils.readBooleanAttribute;
306import static com.android.internal.util.XmlUtils.readIntAttribute;
307import static com.android.internal.util.XmlUtils.readLongAttribute;
308import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
309import static com.android.internal.util.XmlUtils.writeIntAttribute;
310import static com.android.internal.util.XmlUtils.writeLongAttribute;
311import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
312import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
313import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
314import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
315import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
316import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
317import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
318import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
319import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
320import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
321import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
322import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
323import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
324import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
325import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
326import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
327import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
328import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
329import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
330import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
331import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
332import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
333import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
334import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
335import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
336import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
337import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
338import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
339import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
340import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
341import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
342import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
343import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
344import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
345import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
346import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
347import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
348import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
349import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
350import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
351import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
352import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
353import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
354import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
355import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
356import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
357import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
358import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
359import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
360import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
361import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
362import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
363import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
364import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
365import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
366import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
367import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
368import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
369import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
370import static com.android.server.am.ActivityStackSupervisor.CREATE_IF_NEEDED;
371import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
372import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
373import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
374import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
375import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
376import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
377import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
378import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
379import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
380import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
381import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
382import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
383import static com.android.server.wm.AppTransition.TRANSIT_NONE;
384import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
385import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
386import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
387import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
388import static org.xmlpull.v1.XmlPullParser.START_TAG;
389
390public class ActivityManagerService extends IActivityManager.Stub
391        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
392
393    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
394    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
395    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
396    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
397    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
398    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
399    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
400    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
401    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
402    private static final String TAG_LRU = TAG + POSTFIX_LRU;
403    private static final String TAG_MU = TAG + POSTFIX_MU;
404    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
405    private static final String TAG_POWER = TAG + POSTFIX_POWER;
406    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
407    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
408    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
409    private static final String TAG_PSS = TAG + POSTFIX_PSS;
410    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
411    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
412    private static final String TAG_STACK = TAG + POSTFIX_STACK;
413    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
414    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
415    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
416    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
417    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
418
419    // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
420    // here so that while the job scheduler can depend on AMS, the other way around
421    // need not be the case.
422    public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
423
424    /** Control over CPU and battery monitoring */
425    // write battery stats every 30 minutes.
426    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
427    static final boolean MONITOR_CPU_USAGE = true;
428    // don't sample cpu less than every 5 seconds.
429    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
430    // wait possibly forever for next cpu sample.
431    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
432    static final boolean MONITOR_THREAD_CPU_USAGE = false;
433
434    // The flags that are set for all calls we make to the package manager.
435    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
436
437    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
438
439    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
440
441    // Amount of time after a call to stopAppSwitches() during which we will
442    // prevent further untrusted switches from happening.
443    static final long APP_SWITCH_DELAY_TIME = 5*1000;
444
445    // How long we wait for a launched process to attach to the activity manager
446    // before we decide it's never going to come up for real.
447    static final int PROC_START_TIMEOUT = 10*1000;
448    // How long we wait for an attached process to publish its content providers
449    // before we decide it must be hung.
450    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
451
452    // How long we will retain processes hosting content providers in the "last activity"
453    // state before allowing them to drop down to the regular cached LRU list.  This is
454    // to avoid thrashing of provider processes under low memory situations.
455    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
456
457    // How long we wait for a launched process to attach to the activity manager
458    // before we decide it's never going to come up for real, when the process was
459    // started with a wrapper for instrumentation (such as Valgrind) because it
460    // could take much longer than usual.
461    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
462
463    // How long to wait after going idle before forcing apps to GC.
464    static final int GC_TIMEOUT = 5*1000;
465
466    // The minimum amount of time between successive GC requests for a process.
467    static final int GC_MIN_INTERVAL = 60*1000;
468
469    // The minimum amount of time between successive PSS requests for a process.
470    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
471
472    // The minimum amount of time between successive PSS requests for a process
473    // when the request is due to the memory state being lowered.
474    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
475
476    // The rate at which we check for apps using excessive power -- 15 mins.
477    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
478
479    // The minimum sample duration we will allow before deciding we have
480    // enough data on wake locks to start killing things.
481    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
482
483    // The minimum sample duration we will allow before deciding we have
484    // enough data on CPU usage to start killing things.
485    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
486
487    // How long we allow a receiver to run before giving up on it.
488    static final int BROADCAST_FG_TIMEOUT = 10*1000;
489    static final int BROADCAST_BG_TIMEOUT = 60*1000;
490
491    // How long we wait until we timeout on key dispatching.
492    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
493
494    // How long we wait until we timeout on key dispatching during instrumentation.
495    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
496
497    // This is the amount of time an app needs to be running a foreground service before
498    // we will consider it to be doing interaction for usage stats.
499    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
500
501    // Maximum amount of time we will allow to elapse before re-reporting usage stats
502    // interaction with foreground processes.
503    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
504
505    // This is the amount of time we allow an app to settle after it goes into the background,
506    // before we start restricting what it can do.
507    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
508
509    // How long to wait in getAssistContextExtras for the activity and foreground services
510    // to respond with the result.
511    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
512
513    // How long top wait when going through the modern assist (which doesn't need to block
514    // on getting this result before starting to launch its UI).
515    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
516
517    // How long to wait in getAutoFillAssistStructure() for the activity to respond with the result.
518    static final int PENDING_AUTO_FILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
519
520    // Maximum number of persisted Uri grants a package is allowed
521    static final int MAX_PERSISTED_URI_GRANTS = 128;
522
523    static final int MY_PID = Process.myPid();
524
525    static final String[] EMPTY_STRING_ARRAY = new String[0];
526
527    // How many bytes to write into the dropbox log before truncating
528    static final int DROPBOX_MAX_SIZE = 192 * 1024;
529    // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
530    // as one line, but close enough for now.
531    static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
532
533    // Access modes for handleIncomingUser.
534    static final int ALLOW_NON_FULL = 0;
535    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
536    static final int ALLOW_FULL_ONLY = 2;
537
538    // Necessary ApplicationInfo flags to mark an app as persistent
539    private static final int PERSISTENT_MASK =
540            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
541
542    // Intent sent when remote bugreport collection has been completed
543    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
544            "android.intent.action.REMOTE_BUGREPORT_FINISHED";
545
546    // Used to indicate that an app transition should be animated.
547    static final boolean ANIMATE = true;
548
549    // Determines whether to take full screen screenshots
550    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
551    public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
552
553    /** All system services */
554    SystemServiceManager mSystemServiceManager;
555
556    private Installer mInstaller;
557
558    /** Run all ActivityStacks through this */
559    final ActivityStackSupervisor mStackSupervisor;
560    private final KeyguardController mKeyguardController;
561
562    final ActivityStarter mActivityStarter;
563
564    final TaskChangeNotificationController mTaskChangeNotificationController;
565
566    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
567
568    public IntentFirewall mIntentFirewall;
569
570    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
571    // default action automatically.  Important for devices without direct input
572    // devices.
573    private boolean mShowDialogs = true;
574    private boolean mInVrMode = false;
575
576    // Whether we should use SCHED_FIFO for UI and RenderThreads.
577    private boolean mUseFifoUiScheduling = false;
578
579    BroadcastQueue mFgBroadcastQueue;
580    BroadcastQueue mBgBroadcastQueue;
581    // Convenient for easy iteration over the queues. Foreground is first
582    // so that dispatch of foreground broadcasts gets precedence.
583    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
584
585    BroadcastStats mLastBroadcastStats;
586    BroadcastStats mCurBroadcastStats;
587
588    BroadcastQueue broadcastQueueForIntent(Intent intent) {
589        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
590        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
591                "Broadcast intent " + intent + " on "
592                + (isFg ? "foreground" : "background") + " queue");
593        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
594    }
595
596    /**
597     * The last resumed activity. This is identical to the current resumed activity most
598     * of the time but could be different when we're pausing one activity before we resume
599     * another activity.
600     */
601    private ActivityRecord mLastResumedActivity;
602
603    /**
604     * If non-null, we are tracking the time the user spends in the currently focused app.
605     */
606    private AppTimeTracker mCurAppTimeTracker;
607
608    /**
609     * List of intents that were used to start the most recent tasks.
610     */
611    final RecentTasks mRecentTasks;
612
613    /**
614     * For addAppTask: cached of the last activity component that was added.
615     */
616    ComponentName mLastAddedTaskComponent;
617
618    /**
619     * For addAppTask: cached of the last activity uid that was added.
620     */
621    int mLastAddedTaskUid;
622
623    /**
624     * For addAppTask: cached of the last ActivityInfo that was added.
625     */
626    ActivityInfo mLastAddedTaskActivity;
627
628    /**
629     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
630     */
631    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
632
633    /**
634     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
635     */
636    String mDeviceOwnerName;
637
638    final UserController mUserController;
639
640    final AppErrors mAppErrors;
641
642    public boolean canShowErrorDialogs() {
643        return mShowDialogs && !mSleeping && !mShuttingDown
644                && !mKeyguardController.isKeyguardShowing();
645    }
646
647    private static final class PriorityState {
648        // Acts as counter for number of synchronized region that needs to acquire 'this' as a lock
649        // the current thread is currently in. When it drops down to zero, we will no longer boost
650        // the thread's priority.
651        private int regionCounter = 0;
652
653        // The thread's previous priority before boosting.
654        private int prevPriority = Integer.MIN_VALUE;
655    }
656
657    static ThreadLocal<PriorityState> sThreadPriorityState = new ThreadLocal<PriorityState>() {
658        @Override protected PriorityState initialValue() {
659            return new PriorityState();
660        }
661    };
662
663    static void boostPriorityForLockedSection() {
664        int tid = Process.myTid();
665        int prevPriority = Process.getThreadPriority(tid);
666        PriorityState state = sThreadPriorityState.get();
667        if (state.regionCounter == 0 && prevPriority > -2) {
668            state.prevPriority = prevPriority;
669            Process.setThreadPriority(tid, -2);
670        }
671        state.regionCounter++;
672    }
673
674    static void resetPriorityAfterLockedSection() {
675        PriorityState state = sThreadPriorityState.get();
676        state.regionCounter--;
677        if (state.regionCounter == 0 && state.prevPriority > -2) {
678            Process.setThreadPriority(Process.myTid(), state.prevPriority);
679        }
680    }
681
682    public class PendingAssistExtras extends Binder implements Runnable {
683        public final ActivityRecord activity;
684        public final Bundle extras;
685        public final Intent intent;
686        public final String hint;
687        public final IResultReceiver receiver;
688        public final int userHandle;
689        public boolean haveResult = false;
690        public Bundle result = null;
691        public AssistStructure structure = null;
692        public AssistContent content = null;
693        public Bundle receiverExtras;
694        public int resultCode;
695        public int flags;
696
697        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
698                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _resultCode,
699                int _userHandle, int _flags) {
700            activity = _activity;
701            extras = _extras;
702            intent = _intent;
703            hint = _hint;
704            receiver = _receiver;
705            receiverExtras = _receiverExtras;
706            resultCode = _resultCode;
707            userHandle = _userHandle;
708            flags = _flags;
709        }
710        @Override
711        public void run() {
712            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
713            synchronized (this) {
714                haveResult = true;
715                notifyAll();
716            }
717            pendingAssistExtrasTimedOut(this);
718        }
719    }
720
721    final ArrayList<PendingAssistExtras> mPendingAssistExtras
722            = new ArrayList<PendingAssistExtras>();
723
724    /**
725     * Process management.
726     */
727    final ProcessList mProcessList = new ProcessList();
728
729    /**
730     * All of the applications we currently have running organized by name.
731     * The keys are strings of the application package name (as
732     * returned by the package manager), and the keys are ApplicationRecord
733     * objects.
734     */
735    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
736
737    /**
738     * Tracking long-term execution of processes to look for abuse and other
739     * bad app behavior.
740     */
741    final ProcessStatsService mProcessStats;
742
743    /**
744     * The currently running isolated processes.
745     */
746    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
747
748    /**
749     * Counter for assigning isolated process uids, to avoid frequently reusing the
750     * same ones.
751     */
752    int mNextIsolatedProcessUid = 0;
753
754    /**
755     * The currently running heavy-weight process, if any.
756     */
757    ProcessRecord mHeavyWeightProcess = null;
758
759    /**
760     * All of the processes we currently have running organized by pid.
761     * The keys are the pid running the application.
762     *
763     * <p>NOTE: This object is protected by its own lock, NOT the global
764     * activity manager lock!
765     */
766    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
767
768    /**
769     * All of the processes that have been forced to be foreground.  The key
770     * is the pid of the caller who requested it (we hold a death
771     * link on it).
772     */
773    abstract class ForegroundToken implements IBinder.DeathRecipient {
774        int pid;
775        IBinder token;
776    }
777    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
778
779    /**
780     * List of records for processes that someone had tried to start before the
781     * system was ready.  We don't start them at that point, but ensure they
782     * are started by the time booting is complete.
783     */
784    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
785
786    /**
787     * List of persistent applications that are in the process
788     * of being started.
789     */
790    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
791
792    /**
793     * Processes that are being forcibly torn down.
794     */
795    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
796
797    /**
798     * List of running applications, sorted by recent usage.
799     * The first entry in the list is the least recently used.
800     */
801    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
802
803    /**
804     * Where in mLruProcesses that the processes hosting activities start.
805     */
806    int mLruProcessActivityStart = 0;
807
808    /**
809     * Where in mLruProcesses that the processes hosting services start.
810     * This is after (lower index) than mLruProcessesActivityStart.
811     */
812    int mLruProcessServiceStart = 0;
813
814    /**
815     * List of processes that should gc as soon as things are idle.
816     */
817    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
818
819    /**
820     * Processes we want to collect PSS data from.
821     */
822    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
823
824    private boolean mBinderTransactionTrackingEnabled = false;
825
826    /**
827     * Last time we requested PSS data of all processes.
828     */
829    long mLastFullPssTime = SystemClock.uptimeMillis();
830
831    /**
832     * If set, the next time we collect PSS data we should do a full collection
833     * with data from native processes and the kernel.
834     */
835    boolean mFullPssPending = false;
836
837    /**
838     * This is the process holding what we currently consider to be
839     * the "home" activity.
840     */
841    ProcessRecord mHomeProcess;
842
843    /**
844     * This is the process holding the activity the user last visited that
845     * is in a different process from the one they are currently in.
846     */
847    ProcessRecord mPreviousProcess;
848
849    /**
850     * The time at which the previous process was last visible.
851     */
852    long mPreviousProcessVisibleTime;
853
854    /**
855     * Track all uids that have actively running processes.
856     */
857    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
858
859    /**
860     * This is for verifying the UID report flow.
861     */
862    static final boolean VALIDATE_UID_STATES = true;
863    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
864
865    /**
866     * Packages that the user has asked to have run in screen size
867     * compatibility mode instead of filling the screen.
868     */
869    final CompatModePackages mCompatModePackages;
870
871    /**
872     * Set of IntentSenderRecord objects that are currently active.
873     */
874    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
875            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
876
877    /**
878     * Fingerprints (hashCode()) of stack traces that we've
879     * already logged DropBox entries for.  Guarded by itself.  If
880     * something (rogue user app) forces this over
881     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
882     */
883    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
884    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
885
886    /**
887     * Strict Mode background batched logging state.
888     *
889     * The string buffer is guarded by itself, and its lock is also
890     * used to determine if another batched write is already
891     * in-flight.
892     */
893    private final StringBuilder mStrictModeBuffer = new StringBuilder();
894
895    /**
896     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
897     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
898     */
899    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
900
901    /**
902     * Resolver for broadcast intents to registered receivers.
903     * Holds BroadcastFilter (subclass of IntentFilter).
904     */
905    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
906            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
907        @Override
908        protected boolean allowFilterResult(
909                BroadcastFilter filter, List<BroadcastFilter> dest) {
910            IBinder target = filter.receiverList.receiver.asBinder();
911            for (int i = dest.size() - 1; i >= 0; i--) {
912                if (dest.get(i).receiverList.receiver.asBinder() == target) {
913                    return false;
914                }
915            }
916            return true;
917        }
918
919        @Override
920        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
921            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
922                    || userId == filter.owningUserId) {
923                return super.newResult(filter, match, userId);
924            }
925            return null;
926        }
927
928        @Override
929        protected BroadcastFilter[] newArray(int size) {
930            return new BroadcastFilter[size];
931        }
932
933        @Override
934        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
935            return packageName.equals(filter.packageName);
936        }
937    };
938
939    /**
940     * State of all active sticky broadcasts per user.  Keys are the action of the
941     * sticky Intent, values are an ArrayList of all broadcasted intents with
942     * that action (which should usually be one).  The SparseArray is keyed
943     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
944     * for stickies that are sent to all users.
945     */
946    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
947            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
948
949    final ActiveServices mServices;
950
951    final static class Association {
952        final int mSourceUid;
953        final String mSourceProcess;
954        final int mTargetUid;
955        final ComponentName mTargetComponent;
956        final String mTargetProcess;
957
958        int mCount;
959        long mTime;
960
961        int mNesting;
962        long mStartTime;
963
964        // states of the source process when the bind occurred.
965        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
966        long mLastStateUptime;
967        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
968                - ActivityManager.MIN_PROCESS_STATE+1];
969
970        Association(int sourceUid, String sourceProcess, int targetUid,
971                ComponentName targetComponent, String targetProcess) {
972            mSourceUid = sourceUid;
973            mSourceProcess = sourceProcess;
974            mTargetUid = targetUid;
975            mTargetComponent = targetComponent;
976            mTargetProcess = targetProcess;
977        }
978    }
979
980    /**
981     * When service association tracking is enabled, this is all of the associations we
982     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
983     * -> association data.
984     */
985    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
986            mAssociations = new SparseArray<>();
987    boolean mTrackingAssociations;
988
989    /**
990     * Backup/restore process management
991     */
992    String mBackupAppName = null;
993    BackupRecord mBackupTarget = null;
994
995    final ProviderMap mProviderMap;
996
997    /**
998     * List of content providers who have clients waiting for them.  The
999     * application is currently being launched and the provider will be
1000     * removed from this list once it is published.
1001     */
1002    final ArrayList<ContentProviderRecord> mLaunchingProviders
1003            = new ArrayList<ContentProviderRecord>();
1004
1005    /**
1006     * File storing persisted {@link #mGrantedUriPermissions}.
1007     */
1008    private final AtomicFile mGrantFile;
1009
1010    /** XML constants used in {@link #mGrantFile} */
1011    private static final String TAG_URI_GRANTS = "uri-grants";
1012    private static final String TAG_URI_GRANT = "uri-grant";
1013    private static final String ATTR_USER_HANDLE = "userHandle";
1014    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
1015    private static final String ATTR_TARGET_USER_ID = "targetUserId";
1016    private static final String ATTR_SOURCE_PKG = "sourcePkg";
1017    private static final String ATTR_TARGET_PKG = "targetPkg";
1018    private static final String ATTR_URI = "uri";
1019    private static final String ATTR_MODE_FLAGS = "modeFlags";
1020    private static final String ATTR_CREATED_TIME = "createdTime";
1021    private static final String ATTR_PREFIX = "prefix";
1022
1023    /**
1024     * Global set of specific {@link Uri} permissions that have been granted.
1025     * This optimized lookup structure maps from {@link UriPermission#targetUid}
1026     * to {@link UriPermission#uri} to {@link UriPermission}.
1027     */
1028    @GuardedBy("this")
1029    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1030            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1031
1032    public static class GrantUri {
1033        public final int sourceUserId;
1034        public final Uri uri;
1035        public boolean prefix;
1036
1037        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1038            this.sourceUserId = sourceUserId;
1039            this.uri = uri;
1040            this.prefix = prefix;
1041        }
1042
1043        @Override
1044        public int hashCode() {
1045            int hashCode = 1;
1046            hashCode = 31 * hashCode + sourceUserId;
1047            hashCode = 31 * hashCode + uri.hashCode();
1048            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1049            return hashCode;
1050        }
1051
1052        @Override
1053        public boolean equals(Object o) {
1054            if (o instanceof GrantUri) {
1055                GrantUri other = (GrantUri) o;
1056                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1057                        && prefix == other.prefix;
1058            }
1059            return false;
1060        }
1061
1062        @Override
1063        public String toString() {
1064            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1065            if (prefix) result += " [prefix]";
1066            return result;
1067        }
1068
1069        public String toSafeString() {
1070            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1071            if (prefix) result += " [prefix]";
1072            return result;
1073        }
1074
1075        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1076            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1077                    ContentProvider.getUriWithoutUserId(uri), false);
1078        }
1079    }
1080
1081    CoreSettingsObserver mCoreSettingsObserver;
1082
1083    FontScaleSettingObserver mFontScaleSettingObserver;
1084
1085    private final class FontScaleSettingObserver extends ContentObserver {
1086        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1087
1088        public FontScaleSettingObserver() {
1089            super(mHandler);
1090            ContentResolver resolver = mContext.getContentResolver();
1091            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1092        }
1093
1094        @Override
1095        public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1096            if (mFontScaleUri.equals(uri)) {
1097                updateFontScaleIfNeeded(userId);
1098            }
1099        }
1100    }
1101
1102    /**
1103     * Thread-local storage used to carry caller permissions over through
1104     * indirect content-provider access.
1105     */
1106    private class Identity {
1107        public final IBinder token;
1108        public final int pid;
1109        public final int uid;
1110
1111        Identity(IBinder _token, int _pid, int _uid) {
1112            token = _token;
1113            pid = _pid;
1114            uid = _uid;
1115        }
1116    }
1117
1118    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1119
1120    /**
1121     * All information we have collected about the runtime performance of
1122     * any user id that can impact battery performance.
1123     */
1124    final BatteryStatsService mBatteryStatsService;
1125
1126    /**
1127     * Information about component usage
1128     */
1129    UsageStatsManagerInternal mUsageStatsService;
1130
1131    /**
1132     * Access to DeviceIdleController service.
1133     */
1134    DeviceIdleController.LocalService mLocalDeviceIdleController;
1135
1136    /**
1137     * Information about and control over application operations
1138     */
1139    final AppOpsService mAppOpsService;
1140
1141    /** Current sequencing integer of the configuration, for skipping old configurations. */
1142    private int mConfigurationSeq;
1143
1144    /**
1145     * Temp object used when global and/or display override configuration is updated. It is also
1146     * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
1147     * anyone...
1148     */
1149    private Configuration mTempConfig = new Configuration();
1150
1151    private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
1152            new UpdateConfigurationResult();
1153    private static final class UpdateConfigurationResult {
1154        // Configuration changes that were updated.
1155        int changes;
1156        // If the activity was relaunched to match the new configuration.
1157        boolean activityRelaunched;
1158
1159        void reset() {
1160            changes = 0;
1161            activityRelaunched = false;
1162        }
1163    }
1164
1165    boolean mSuppressResizeConfigChanges;
1166
1167    /**
1168     * Hardware-reported OpenGLES version.
1169     */
1170    final int GL_ES_VERSION;
1171
1172    /**
1173     * List of initialization arguments to pass to all processes when binding applications to them.
1174     * For example, references to the commonly used services.
1175     */
1176    HashMap<String, IBinder> mAppBindArgs;
1177    HashMap<String, IBinder> mIsolatedAppBindArgs;
1178
1179    /**
1180     * Temporary to avoid allocations.  Protected by main lock.
1181     */
1182    final StringBuilder mStringBuilder = new StringBuilder(256);
1183
1184    /**
1185     * Used to control how we initialize the service.
1186     */
1187    ComponentName mTopComponent;
1188    String mTopAction = Intent.ACTION_MAIN;
1189    String mTopData;
1190
1191    volatile boolean mProcessesReady = false;
1192    volatile boolean mSystemReady = false;
1193    volatile boolean mOnBattery = false;
1194    volatile int mFactoryTest;
1195
1196    @GuardedBy("this") boolean mBooting = false;
1197    @GuardedBy("this") boolean mCallFinishBooting = false;
1198    @GuardedBy("this") boolean mBootAnimationComplete = false;
1199    @GuardedBy("this") boolean mLaunchWarningShown = false;
1200    @GuardedBy("this") boolean mCheckedForSetup = false;
1201
1202    Context mContext;
1203
1204    /**
1205     * The time at which we will allow normal application switches again,
1206     * after a call to {@link #stopAppSwitches()}.
1207     */
1208    long mAppSwitchesAllowedTime;
1209
1210    /**
1211     * This is set to true after the first switch after mAppSwitchesAllowedTime
1212     * is set; any switches after that will clear the time.
1213     */
1214    boolean mDidAppSwitch;
1215
1216    /**
1217     * Last time (in realtime) at which we checked for power usage.
1218     */
1219    long mLastPowerCheckRealtime;
1220
1221    /**
1222     * Last time (in uptime) at which we checked for power usage.
1223     */
1224    long mLastPowerCheckUptime;
1225
1226    /**
1227     * Set while we are wanting to sleep, to prevent any
1228     * activities from being started/resumed.
1229     *
1230     * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
1231     *
1232     * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
1233     * while in the sleep state until there is a pending transition out of sleep, in which case
1234     * mSleeping is set to false, and remains false while awake.
1235     *
1236     * Whether mSleeping can quickly toggled between true/false without the device actually
1237     * display changing states is undefined.
1238     */
1239    private boolean mSleeping = false;
1240
1241    /**
1242     * The process state used for processes that are running the top activities.
1243     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1244     */
1245    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1246
1247    /**
1248     * Set while we are running a voice interaction.  This overrides
1249     * sleeping while it is active.
1250     */
1251    private IVoiceInteractionSession mRunningVoice;
1252
1253    /**
1254     * For some direct access we need to power manager.
1255     */
1256    PowerManagerInternal mLocalPowerManager;
1257
1258    /**
1259     * We want to hold a wake lock while running a voice interaction session, since
1260     * this may happen with the screen off and we need to keep the CPU running to
1261     * be able to continue to interact with the user.
1262     */
1263    PowerManager.WakeLock mVoiceWakeLock;
1264
1265    /**
1266     * State of external calls telling us if the device is awake or asleep.
1267     */
1268    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1269
1270    /**
1271     * A list of tokens that cause the top activity to be put to sleep.
1272     * They are used by components that may hide and block interaction with underlying
1273     * activities.
1274     */
1275    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1276
1277    /**
1278     * Set if we are shutting down the system, similar to sleeping.
1279     */
1280    boolean mShuttingDown = false;
1281
1282    /**
1283     * Current sequence id for oom_adj computation traversal.
1284     */
1285    int mAdjSeq = 0;
1286
1287    /**
1288     * Current sequence id for process LRU updating.
1289     */
1290    int mLruSeq = 0;
1291
1292    /**
1293     * Keep track of the non-cached/empty process we last found, to help
1294     * determine how to distribute cached/empty processes next time.
1295     */
1296    int mNumNonCachedProcs = 0;
1297
1298    /**
1299     * Keep track of the number of cached hidden procs, to balance oom adj
1300     * distribution between those and empty procs.
1301     */
1302    int mNumCachedHiddenProcs = 0;
1303
1304    /**
1305     * Keep track of the number of service processes we last found, to
1306     * determine on the next iteration which should be B services.
1307     */
1308    int mNumServiceProcs = 0;
1309    int mNewNumAServiceProcs = 0;
1310    int mNewNumServiceProcs = 0;
1311
1312    /**
1313     * Allow the current computed overall memory level of the system to go down?
1314     * This is set to false when we are killing processes for reasons other than
1315     * memory management, so that the now smaller process list will not be taken as
1316     * an indication that memory is tighter.
1317     */
1318    boolean mAllowLowerMemLevel = false;
1319
1320    /**
1321     * The last computed memory level, for holding when we are in a state that
1322     * processes are going away for other reasons.
1323     */
1324    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1325
1326    /**
1327     * The last total number of process we have, to determine if changes actually look
1328     * like a shrinking number of process due to lower RAM.
1329     */
1330    int mLastNumProcesses;
1331
1332    /**
1333     * The uptime of the last time we performed idle maintenance.
1334     */
1335    long mLastIdleTime = SystemClock.uptimeMillis();
1336
1337    /**
1338     * Total time spent with RAM that has been added in the past since the last idle time.
1339     */
1340    long mLowRamTimeSinceLastIdle = 0;
1341
1342    /**
1343     * If RAM is currently low, when that horrible situation started.
1344     */
1345    long mLowRamStartTime = 0;
1346
1347    /**
1348     * For reporting to battery stats the current top application.
1349     */
1350    private String mCurResumedPackage = null;
1351    private int mCurResumedUid = -1;
1352
1353    /**
1354     * For reporting to battery stats the apps currently running foreground
1355     * service.  The ProcessMap is package/uid tuples; each of these contain
1356     * an array of the currently foreground processes.
1357     */
1358    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1359            = new ProcessMap<ArrayList<ProcessRecord>>();
1360
1361    /**
1362     * This is set if we had to do a delayed dexopt of an app before launching
1363     * it, to increase the ANR timeouts in that case.
1364     */
1365    boolean mDidDexOpt;
1366
1367    /**
1368     * Set if the systemServer made a call to enterSafeMode.
1369     */
1370    boolean mSafeMode;
1371
1372    /**
1373     * If true, we are running under a test environment so will sample PSS from processes
1374     * much more rapidly to try to collect better data when the tests are rapidly
1375     * running through apps.
1376     */
1377    boolean mTestPssMode = false;
1378
1379    String mDebugApp = null;
1380    boolean mWaitForDebugger = false;
1381    boolean mDebugTransient = false;
1382    String mOrigDebugApp = null;
1383    boolean mOrigWaitForDebugger = false;
1384    boolean mAlwaysFinishActivities = false;
1385    boolean mForceResizableActivities;
1386    boolean mSupportsMultiWindow;
1387    boolean mSupportsSplitScreenMultiWindow;
1388    boolean mSupportsFreeformWindowManagement;
1389    boolean mSupportsPictureInPicture;
1390    boolean mSupportsLeanbackOnly;
1391    IActivityController mController = null;
1392    boolean mControllerIsAMonkey = false;
1393    String mProfileApp = null;
1394    ProcessRecord mProfileProc = null;
1395    String mProfileFile;
1396    ParcelFileDescriptor mProfileFd;
1397    int mSamplingInterval = 0;
1398    boolean mAutoStopProfiler = false;
1399    int mProfileType = 0;
1400    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1401    String mMemWatchDumpProcName;
1402    String mMemWatchDumpFile;
1403    int mMemWatchDumpPid;
1404    int mMemWatchDumpUid;
1405    String mTrackAllocationApp = null;
1406    String mNativeDebuggingApp = null;
1407
1408    final long[] mTmpLong = new long[2];
1409
1410    private final ArraySet<BroadcastQueue> mTmpBroadcastQueue = new ArraySet();
1411
1412    static final class ProcessChangeItem {
1413        static final int CHANGE_ACTIVITIES = 1<<0;
1414        static final int CHANGE_PROCESS_STATE = 1<<1;
1415        int changes;
1416        int uid;
1417        int pid;
1418        int processState;
1419        boolean foregroundActivities;
1420    }
1421
1422    static final class UidObserverRegistration {
1423        final int uid;
1424        final String pkg;
1425        final int which;
1426        final int cutpoint;
1427
1428        final SparseIntArray lastProcStates;
1429
1430        UidObserverRegistration(int _uid, String _pkg, int _which, int _cutpoint) {
1431            uid = _uid;
1432            pkg = _pkg;
1433            which = _which;
1434            cutpoint = _cutpoint;
1435            if (cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
1436                lastProcStates = new SparseIntArray();
1437            } else {
1438                lastProcStates = null;
1439            }
1440        }
1441    }
1442
1443    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1444    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1445
1446    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1447    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1448
1449    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1450    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1451
1452    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1453    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1454
1455    /**
1456     * Runtime CPU use collection thread.  This object's lock is used to
1457     * perform synchronization with the thread (notifying it to run).
1458     */
1459    final Thread mProcessCpuThread;
1460
1461    /**
1462     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1463     * Must acquire this object's lock when accessing it.
1464     * NOTE: this lock will be held while doing long operations (trawling
1465     * through all processes in /proc), so it should never be acquired by
1466     * any critical paths such as when holding the main activity manager lock.
1467     */
1468    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1469            MONITOR_THREAD_CPU_USAGE);
1470    final AtomicLong mLastCpuTime = new AtomicLong(0);
1471    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1472    final CountDownLatch mProcessCpuInitLatch = new CountDownLatch(1);
1473
1474    long mLastWriteTime = 0;
1475
1476    /**
1477     * Used to retain an update lock when the foreground activity is in
1478     * immersive mode.
1479     */
1480    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1481
1482    /**
1483     * Set to true after the system has finished booting.
1484     */
1485    boolean mBooted = false;
1486
1487    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1488    int mProcessLimitOverride = -1;
1489
1490    WindowManagerService mWindowManager;
1491    final ActivityThread mSystemThread;
1492
1493    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1494        final ProcessRecord mApp;
1495        final int mPid;
1496        final IApplicationThread mAppThread;
1497
1498        AppDeathRecipient(ProcessRecord app, int pid,
1499                IApplicationThread thread) {
1500            if (DEBUG_ALL) Slog.v(
1501                TAG, "New death recipient " + this
1502                + " for thread " + thread.asBinder());
1503            mApp = app;
1504            mPid = pid;
1505            mAppThread = thread;
1506        }
1507
1508        @Override
1509        public void binderDied() {
1510            if (DEBUG_ALL) Slog.v(
1511                TAG, "Death received in " + this
1512                + " for thread " + mAppThread.asBinder());
1513            synchronized(ActivityManagerService.this) {
1514                appDiedLocked(mApp, mPid, mAppThread, true);
1515            }
1516        }
1517    }
1518
1519    static final int SHOW_ERROR_UI_MSG = 1;
1520    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1521    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1522    static final int UPDATE_CONFIGURATION_MSG = 4;
1523    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1524    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1525    static final int SERVICE_TIMEOUT_MSG = 12;
1526    static final int UPDATE_TIME_ZONE = 13;
1527    static final int SHOW_UID_ERROR_UI_MSG = 14;
1528    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1529    static final int PROC_START_TIMEOUT_MSG = 20;
1530    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1531    static final int KILL_APPLICATION_MSG = 22;
1532    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1533    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1534    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1535    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1536    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1537    static final int CLEAR_DNS_CACHE_MSG = 28;
1538    static final int UPDATE_HTTP_PROXY_MSG = 29;
1539    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1540    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1541    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1542    static final int REPORT_MEM_USAGE_MSG = 33;
1543    static final int REPORT_USER_SWITCH_MSG = 34;
1544    static final int CONTINUE_USER_SWITCH_MSG = 35;
1545    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1546    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1547    static final int PERSIST_URI_GRANTS_MSG = 38;
1548    static final int REQUEST_ALL_PSS_MSG = 39;
1549    static final int START_PROFILES_MSG = 40;
1550    static final int UPDATE_TIME_PREFERENCE_MSG = 41;
1551    static final int SYSTEM_USER_START_MSG = 42;
1552    static final int SYSTEM_USER_CURRENT_MSG = 43;
1553    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1554    static final int FINISH_BOOTING_MSG = 45;
1555    static final int START_USER_SWITCH_UI_MSG = 46;
1556    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1557    static final int DISMISS_DIALOG_UI_MSG = 48;
1558    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 49;
1559    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 50;
1560    static final int DELETE_DUMPHEAP_MSG = 51;
1561    static final int FOREGROUND_PROFILE_CHANGED_MSG = 52;
1562    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 53;
1563    static final int REPORT_TIME_TRACKER_MSG = 54;
1564    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 55;
1565    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 56;
1566    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 57;
1567    static final int IDLE_UIDS_MSG = 58;
1568    static final int SYSTEM_USER_UNLOCK_MSG = 59;
1569    static final int LOG_STACK_STATE = 60;
1570    static final int VR_MODE_CHANGE_MSG = 61;
1571    static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 62;
1572    static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 63;
1573    static final int REPORT_LOCKED_BOOT_COMPLETE_MSG = 64;
1574    static final int NOTIFY_VR_SLEEPING_MSG = 65;
1575    static final int START_USER_SWITCH_FG_MSG = 712;
1576
1577    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1578    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1579    static final int FIRST_COMPAT_MODE_MSG = 300;
1580    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1581
1582    static ServiceThread sKillThread = null;
1583    static KillHandler sKillHandler = null;
1584
1585    CompatModeDialog mCompatModeDialog;
1586    UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1587    long mLastMemUsageReportTime = 0;
1588
1589    /**
1590     * Flag whether the current user is a "monkey", i.e. whether
1591     * the UI is driven by a UI automation tool.
1592     */
1593    private boolean mUserIsMonkey;
1594
1595    /** Flag whether the device has a Recents UI */
1596    boolean mHasRecents;
1597
1598    /** The dimensions of the thumbnails in the Recents UI. */
1599    int mThumbnailWidth;
1600    int mThumbnailHeight;
1601    float mFullscreenThumbnailScale;
1602
1603    /** The aspect ratio bounds of the PIP. */
1604    float mMinPipAspectRatio;
1605    float mMaxPipAspectRatio;
1606
1607    final ServiceThread mHandlerThread;
1608    final MainHandler mHandler;
1609    final UiHandler mUiHandler;
1610
1611    PackageManagerInternal mPackageManagerInt;
1612
1613    // VoiceInteraction session ID that changes for each new request except when
1614    // being called for multiwindow assist in a single session.
1615    private int mViSessionId = 1000;
1616
1617    final boolean mPermissionReviewRequired;
1618
1619    /**
1620     * Current global configuration information. Contains general settings for the entire system,
1621     * also corresponds to the merged configuration of the default display.
1622     */
1623    Configuration getGlobalConfiguration() {
1624        return mStackSupervisor.getConfiguration();
1625    }
1626
1627    final class KillHandler extends Handler {
1628        static final int KILL_PROCESS_GROUP_MSG = 4000;
1629
1630        public KillHandler(Looper looper) {
1631            super(looper, null, true);
1632        }
1633
1634        @Override
1635        public void handleMessage(Message msg) {
1636            switch (msg.what) {
1637                case KILL_PROCESS_GROUP_MSG:
1638                {
1639                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1640                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1641                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1642                }
1643                break;
1644
1645                default:
1646                    super.handleMessage(msg);
1647            }
1648        }
1649    }
1650
1651    final class UiHandler extends Handler {
1652        public UiHandler() {
1653            super(com.android.server.UiThread.get().getLooper(), null, true);
1654        }
1655
1656        @Override
1657        public void handleMessage(Message msg) {
1658            switch (msg.what) {
1659            case SHOW_ERROR_UI_MSG: {
1660                mAppErrors.handleShowAppErrorUi(msg);
1661                ensureBootCompleted();
1662            } break;
1663            case SHOW_NOT_RESPONDING_UI_MSG: {
1664                mAppErrors.handleShowAnrUi(msg);
1665                ensureBootCompleted();
1666            } break;
1667            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1668                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1669                synchronized (ActivityManagerService.this) {
1670                    ProcessRecord proc = (ProcessRecord) data.get("app");
1671                    if (proc == null) {
1672                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1673                        break;
1674                    }
1675                    if (proc.crashDialog != null) {
1676                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1677                        return;
1678                    }
1679                    AppErrorResult res = (AppErrorResult) data.get("result");
1680                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1681                        Dialog d = new StrictModeViolationDialog(mContext,
1682                                ActivityManagerService.this, res, proc);
1683                        d.show();
1684                        proc.crashDialog = d;
1685                    } else {
1686                        // The device is asleep, so just pretend that the user
1687                        // saw a crash dialog and hit "force quit".
1688                        res.set(0);
1689                    }
1690                }
1691                ensureBootCompleted();
1692            } break;
1693            case SHOW_FACTORY_ERROR_UI_MSG: {
1694                Dialog d = new FactoryErrorDialog(
1695                    mContext, msg.getData().getCharSequence("msg"));
1696                d.show();
1697                ensureBootCompleted();
1698            } break;
1699            case WAIT_FOR_DEBUGGER_UI_MSG: {
1700                synchronized (ActivityManagerService.this) {
1701                    ProcessRecord app = (ProcessRecord)msg.obj;
1702                    if (msg.arg1 != 0) {
1703                        if (!app.waitedForDebugger) {
1704                            Dialog d = new AppWaitingForDebuggerDialog(
1705                                    ActivityManagerService.this,
1706                                    mContext, app);
1707                            app.waitDialog = d;
1708                            app.waitedForDebugger = true;
1709                            d.show();
1710                        }
1711                    } else {
1712                        if (app.waitDialog != null) {
1713                            app.waitDialog.dismiss();
1714                            app.waitDialog = null;
1715                        }
1716                    }
1717                }
1718            } break;
1719            case SHOW_UID_ERROR_UI_MSG: {
1720                if (mShowDialogs) {
1721                    AlertDialog d = new BaseErrorDialog(mContext);
1722                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1723                    d.setCancelable(false);
1724                    d.setTitle(mContext.getText(R.string.android_system_label));
1725                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1726                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1727                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1728                    d.show();
1729                }
1730            } break;
1731            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1732                if (mShowDialogs) {
1733                    AlertDialog d = new BaseErrorDialog(mContext);
1734                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1735                    d.setCancelable(false);
1736                    d.setTitle(mContext.getText(R.string.android_system_label));
1737                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1738                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1739                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1740                    d.show();
1741                }
1742            } break;
1743            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1744                synchronized (ActivityManagerService.this) {
1745                    ActivityRecord ar = (ActivityRecord) msg.obj;
1746                    if (mCompatModeDialog != null) {
1747                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1748                                ar.info.applicationInfo.packageName)) {
1749                            return;
1750                        }
1751                        mCompatModeDialog.dismiss();
1752                        mCompatModeDialog = null;
1753                    }
1754                    if (ar != null && false) {
1755                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1756                                ar.packageName)) {
1757                            int mode = mCompatModePackages.computeCompatModeLocked(
1758                                    ar.info.applicationInfo);
1759                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1760                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1761                                mCompatModeDialog = new CompatModeDialog(
1762                                        ActivityManagerService.this, mContext,
1763                                        ar.info.applicationInfo);
1764                                mCompatModeDialog.show();
1765                            }
1766                        }
1767                    }
1768                }
1769                break;
1770            }
1771            case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1772                synchronized (ActivityManagerService.this) {
1773                    final ActivityRecord ar = (ActivityRecord) msg.obj;
1774                    if (mUnsupportedDisplaySizeDialog != null) {
1775                        mUnsupportedDisplaySizeDialog.dismiss();
1776                        mUnsupportedDisplaySizeDialog = null;
1777                    }
1778                    if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1779                            ar.packageName)) {
1780                        // TODO(multi-display): Show dialog on appropriate display.
1781                        mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1782                                ActivityManagerService.this, mContext, ar.info.applicationInfo);
1783                        mUnsupportedDisplaySizeDialog.show();
1784                    }
1785                }
1786                break;
1787            }
1788            case START_USER_SWITCH_UI_MSG: {
1789                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1790                break;
1791            }
1792            case DISMISS_DIALOG_UI_MSG: {
1793                final Dialog d = (Dialog) msg.obj;
1794                d.dismiss();
1795                break;
1796            }
1797            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1798                dispatchProcessesChanged();
1799                break;
1800            }
1801            case DISPATCH_PROCESS_DIED_UI_MSG: {
1802                final int pid = msg.arg1;
1803                final int uid = msg.arg2;
1804                dispatchProcessDied(pid, uid);
1805                break;
1806            }
1807            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1808                dispatchUidsChanged();
1809            } break;
1810            }
1811        }
1812    }
1813
1814    final class MainHandler extends Handler {
1815        public MainHandler(Looper looper) {
1816            super(looper, null, true);
1817        }
1818
1819        @Override
1820        public void handleMessage(Message msg) {
1821            switch (msg.what) {
1822            case UPDATE_CONFIGURATION_MSG: {
1823                final ContentResolver resolver = mContext.getContentResolver();
1824                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1825                        msg.arg1);
1826            } break;
1827            case GC_BACKGROUND_PROCESSES_MSG: {
1828                synchronized (ActivityManagerService.this) {
1829                    performAppGcsIfAppropriateLocked();
1830                }
1831            } break;
1832            case SERVICE_TIMEOUT_MSG: {
1833                if (mDidDexOpt) {
1834                    mDidDexOpt = false;
1835                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1836                    nmsg.obj = msg.obj;
1837                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1838                    return;
1839                }
1840                mServices.serviceTimeout((ProcessRecord)msg.obj);
1841            } break;
1842            case UPDATE_TIME_ZONE: {
1843                synchronized (ActivityManagerService.this) {
1844                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1845                        ProcessRecord r = mLruProcesses.get(i);
1846                        if (r.thread != null) {
1847                            try {
1848                                r.thread.updateTimeZone();
1849                            } catch (RemoteException ex) {
1850                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1851                            }
1852                        }
1853                    }
1854                }
1855            } break;
1856            case CLEAR_DNS_CACHE_MSG: {
1857                synchronized (ActivityManagerService.this) {
1858                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1859                        ProcessRecord r = mLruProcesses.get(i);
1860                        if (r.thread != null) {
1861                            try {
1862                                r.thread.clearDnsCache();
1863                            } catch (RemoteException ex) {
1864                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1865                            }
1866                        }
1867                    }
1868                }
1869            } break;
1870            case UPDATE_HTTP_PROXY_MSG: {
1871                ProxyInfo proxy = (ProxyInfo)msg.obj;
1872                String host = "";
1873                String port = "";
1874                String exclList = "";
1875                Uri pacFileUrl = Uri.EMPTY;
1876                if (proxy != null) {
1877                    host = proxy.getHost();
1878                    port = Integer.toString(proxy.getPort());
1879                    exclList = proxy.getExclusionListAsString();
1880                    pacFileUrl = proxy.getPacFileUrl();
1881                }
1882                synchronized (ActivityManagerService.this) {
1883                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1884                        ProcessRecord r = mLruProcesses.get(i);
1885                        if (r.thread != null) {
1886                            try {
1887                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1888                            } catch (RemoteException ex) {
1889                                Slog.w(TAG, "Failed to update http proxy for: " +
1890                                        r.info.processName);
1891                            }
1892                        }
1893                    }
1894                }
1895            } break;
1896            case PROC_START_TIMEOUT_MSG: {
1897                if (mDidDexOpt) {
1898                    mDidDexOpt = false;
1899                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1900                    nmsg.obj = msg.obj;
1901                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1902                    return;
1903                }
1904                ProcessRecord app = (ProcessRecord)msg.obj;
1905                synchronized (ActivityManagerService.this) {
1906                    processStartTimedOutLocked(app);
1907                }
1908            } break;
1909            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1910                ProcessRecord app = (ProcessRecord)msg.obj;
1911                synchronized (ActivityManagerService.this) {
1912                    processContentProviderPublishTimedOutLocked(app);
1913                }
1914            } break;
1915            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1916                synchronized (ActivityManagerService.this) {
1917                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1918                }
1919            } break;
1920            case KILL_APPLICATION_MSG: {
1921                synchronized (ActivityManagerService.this) {
1922                    final int appId = msg.arg1;
1923                    final int userId = msg.arg2;
1924                    Bundle bundle = (Bundle)msg.obj;
1925                    String pkg = bundle.getString("pkg");
1926                    String reason = bundle.getString("reason");
1927                    forceStopPackageLocked(pkg, appId, false, false, true, false,
1928                            false, userId, reason);
1929                }
1930            } break;
1931            case FINALIZE_PENDING_INTENT_MSG: {
1932                ((PendingIntentRecord)msg.obj).completeFinalize();
1933            } break;
1934            case POST_HEAVY_NOTIFICATION_MSG: {
1935                INotificationManager inm = NotificationManager.getService();
1936                if (inm == null) {
1937                    return;
1938                }
1939
1940                ActivityRecord root = (ActivityRecord)msg.obj;
1941                ProcessRecord process = root.app;
1942                if (process == null) {
1943                    return;
1944                }
1945
1946                try {
1947                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1948                    String text = mContext.getString(R.string.heavy_weight_notification,
1949                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1950                    Notification notification = new Notification.Builder(context)
1951                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1952                            .setWhen(0)
1953                            .setOngoing(true)
1954                            .setTicker(text)
1955                            .setColor(mContext.getColor(
1956                                    com.android.internal.R.color.system_notification_accent_color))
1957                            .setContentTitle(text)
1958                            .setContentText(
1959                                    mContext.getText(R.string.heavy_weight_notification_detail))
1960                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1961                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1962                                    new UserHandle(root.userId)))
1963                            .build();
1964                    try {
1965                        int[] outId = new int[1];
1966                        inm.enqueueNotificationWithTag("android", "android", null,
1967                                R.string.heavy_weight_notification,
1968                                notification, outId, root.userId);
1969                    } catch (RuntimeException e) {
1970                        Slog.w(ActivityManagerService.TAG,
1971                                "Error showing notification for heavy-weight app", e);
1972                    } catch (RemoteException e) {
1973                    }
1974                } catch (NameNotFoundException e) {
1975                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1976                }
1977            } break;
1978            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1979                INotificationManager inm = NotificationManager.getService();
1980                if (inm == null) {
1981                    return;
1982                }
1983                try {
1984                    inm.cancelNotificationWithTag("android", null,
1985                            R.string.heavy_weight_notification,  msg.arg1);
1986                } catch (RuntimeException e) {
1987                    Slog.w(ActivityManagerService.TAG,
1988                            "Error canceling notification for service", e);
1989                } catch (RemoteException e) {
1990                }
1991            } break;
1992            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1993                synchronized (ActivityManagerService.this) {
1994                    checkExcessivePowerUsageLocked(true);
1995                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1996                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1997                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1998                }
1999            } break;
2000            case REPORT_MEM_USAGE_MSG: {
2001                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
2002                Thread thread = new Thread() {
2003                    @Override public void run() {
2004                        reportMemUsage(memInfos);
2005                    }
2006                };
2007                thread.start();
2008                break;
2009            }
2010            case START_USER_SWITCH_FG_MSG: {
2011                mUserController.startUserInForeground(msg.arg1);
2012                break;
2013            }
2014            case REPORT_USER_SWITCH_MSG: {
2015                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2016                break;
2017            }
2018            case CONTINUE_USER_SWITCH_MSG: {
2019                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2020                break;
2021            }
2022            case USER_SWITCH_TIMEOUT_MSG: {
2023                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2024                break;
2025            }
2026            case IMMERSIVE_MODE_LOCK_MSG: {
2027                final boolean nextState = (msg.arg1 != 0);
2028                if (mUpdateLock.isHeld() != nextState) {
2029                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
2030                            "Applying new update lock state '" + nextState
2031                            + "' for " + (ActivityRecord)msg.obj);
2032                    if (nextState) {
2033                        mUpdateLock.acquire();
2034                    } else {
2035                        mUpdateLock.release();
2036                    }
2037                }
2038                break;
2039            }
2040            case PERSIST_URI_GRANTS_MSG: {
2041                writeGrantedUriPermissions();
2042                break;
2043            }
2044            case REQUEST_ALL_PSS_MSG: {
2045                synchronized (ActivityManagerService.this) {
2046                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
2047                }
2048                break;
2049            }
2050            case START_PROFILES_MSG: {
2051                synchronized (ActivityManagerService.this) {
2052                    mUserController.startProfilesLocked();
2053                }
2054                break;
2055            }
2056            case UPDATE_TIME_PREFERENCE_MSG: {
2057                // The user's time format preference might have changed.
2058                // For convenience we re-use the Intent extra values.
2059                synchronized (ActivityManagerService.this) {
2060                    for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2061                        ProcessRecord r = mLruProcesses.get(i);
2062                        if (r.thread != null) {
2063                            try {
2064                                r.thread.updateTimePrefs(msg.arg1);
2065                            } catch (RemoteException ex) {
2066                                Slog.w(TAG, "Failed to update preferences for: "
2067                                        + r.info.processName);
2068                            }
2069                        }
2070                    }
2071                }
2072                break;
2073            }
2074            case SYSTEM_USER_START_MSG: {
2075                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2076                        Integer.toString(msg.arg1), msg.arg1);
2077                mSystemServiceManager.startUser(msg.arg1);
2078                break;
2079            }
2080            case SYSTEM_USER_UNLOCK_MSG: {
2081                final int userId = msg.arg1;
2082                mSystemServiceManager.unlockUser(userId);
2083                synchronized (ActivityManagerService.this) {
2084                    mRecentTasks.loadUserRecentsLocked(userId);
2085                }
2086                if (userId == UserHandle.USER_SYSTEM) {
2087                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2088                }
2089                installEncryptionUnawareProviders(userId);
2090                mUserController.finishUserUnlocked((UserState) msg.obj);
2091                break;
2092            }
2093            case SYSTEM_USER_CURRENT_MSG: {
2094                mBatteryStatsService.noteEvent(
2095                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2096                        Integer.toString(msg.arg2), msg.arg2);
2097                mBatteryStatsService.noteEvent(
2098                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2099                        Integer.toString(msg.arg1), msg.arg1);
2100                mSystemServiceManager.switchUser(msg.arg1);
2101                break;
2102            }
2103            case ENTER_ANIMATION_COMPLETE_MSG: {
2104                synchronized (ActivityManagerService.this) {
2105                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2106                    if (r != null && r.app != null && r.app.thread != null) {
2107                        try {
2108                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2109                        } catch (RemoteException e) {
2110                        }
2111                    }
2112                }
2113                break;
2114            }
2115            case FINISH_BOOTING_MSG: {
2116                if (msg.arg1 != 0) {
2117                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2118                    finishBooting();
2119                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2120                }
2121                if (msg.arg2 != 0) {
2122                    enableScreenAfterBoot();
2123                }
2124                break;
2125            }
2126            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2127                try {
2128                    Locale l = (Locale) msg.obj;
2129                    IBinder service = ServiceManager.getService("mount");
2130                    IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
2131                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2132                    storageManager.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2133                } catch (RemoteException e) {
2134                    Log.e(TAG, "Error storing locale for decryption UI", e);
2135                }
2136                break;
2137            }
2138            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2139                final int uid = msg.arg1;
2140                final byte[] firstPacket = (byte[]) msg.obj;
2141
2142                synchronized (mPidsSelfLocked) {
2143                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2144                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2145                        if (p.uid == uid) {
2146                            try {
2147                                p.thread.notifyCleartextNetwork(firstPacket);
2148                            } catch (RemoteException ignored) {
2149                            }
2150                        }
2151                    }
2152                }
2153                break;
2154            }
2155            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2156                final String procName;
2157                final int uid;
2158                final long memLimit;
2159                final String reportPackage;
2160                synchronized (ActivityManagerService.this) {
2161                    procName = mMemWatchDumpProcName;
2162                    uid = mMemWatchDumpUid;
2163                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2164                    if (val == null) {
2165                        val = mMemWatchProcesses.get(procName, 0);
2166                    }
2167                    if (val != null) {
2168                        memLimit = val.first;
2169                        reportPackage = val.second;
2170                    } else {
2171                        memLimit = 0;
2172                        reportPackage = null;
2173                    }
2174                }
2175                if (procName == null) {
2176                    return;
2177                }
2178
2179                if (DEBUG_PSS) Slog.d(TAG_PSS,
2180                        "Showing dump heap notification from " + procName + "/" + uid);
2181
2182                INotificationManager inm = NotificationManager.getService();
2183                if (inm == null) {
2184                    return;
2185                }
2186
2187                String text = mContext.getString(R.string.dump_heap_notification, procName);
2188
2189
2190                Intent deleteIntent = new Intent();
2191                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2192                Intent intent = new Intent();
2193                intent.setClassName("android", DumpHeapActivity.class.getName());
2194                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2195                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2196                if (reportPackage != null) {
2197                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2198                }
2199                int userId = UserHandle.getUserId(uid);
2200                Notification notification = new Notification.Builder(mContext)
2201                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2202                        .setWhen(0)
2203                        .setOngoing(true)
2204                        .setAutoCancel(true)
2205                        .setTicker(text)
2206                        .setColor(mContext.getColor(
2207                                com.android.internal.R.color.system_notification_accent_color))
2208                        .setContentTitle(text)
2209                        .setContentText(
2210                                mContext.getText(R.string.dump_heap_notification_detail))
2211                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2212                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2213                                new UserHandle(userId)))
2214                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2215                                deleteIntent, 0, UserHandle.SYSTEM))
2216                        .build();
2217
2218                try {
2219                    int[] outId = new int[1];
2220                    inm.enqueueNotificationWithTag("android", "android", null,
2221                            R.string.dump_heap_notification,
2222                            notification, outId, userId);
2223                } catch (RuntimeException e) {
2224                    Slog.w(ActivityManagerService.TAG,
2225                            "Error showing notification for dump heap", e);
2226                } catch (RemoteException e) {
2227                }
2228            } break;
2229            case DELETE_DUMPHEAP_MSG: {
2230                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2231                        DumpHeapActivity.JAVA_URI,
2232                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2233                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2234                        UserHandle.myUserId());
2235                synchronized (ActivityManagerService.this) {
2236                    mMemWatchDumpFile = null;
2237                    mMemWatchDumpProcName = null;
2238                    mMemWatchDumpPid = -1;
2239                    mMemWatchDumpUid = -1;
2240                }
2241            } break;
2242            case FOREGROUND_PROFILE_CHANGED_MSG: {
2243                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2244            } break;
2245            case REPORT_TIME_TRACKER_MSG: {
2246                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2247                tracker.deliverResult(mContext);
2248            } break;
2249            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2250                mUserController.dispatchUserSwitchComplete(msg.arg1);
2251            } break;
2252            case REPORT_LOCKED_BOOT_COMPLETE_MSG: {
2253                mUserController.dispatchLockedBootComplete(msg.arg1);
2254            } break;
2255            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2256                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2257                try {
2258                    connection.shutdown();
2259                } catch (RemoteException e) {
2260                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2261                }
2262                // Only a UiAutomation can set this flag and now that
2263                // it is finished we make sure it is reset to its default.
2264                mUserIsMonkey = false;
2265            } break;
2266            case IDLE_UIDS_MSG: {
2267                idleUids();
2268            } break;
2269            case VR_MODE_CHANGE_MSG: {
2270                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2271                if (vrService == null) {
2272                    break;
2273                }
2274                final ActivityRecord r = (ActivityRecord) msg.obj;
2275                boolean vrMode;
2276                ComponentName requestedPackage;
2277                ComponentName callingPackage;
2278                int userId;
2279                synchronized (ActivityManagerService.this) {
2280                    vrMode = r.requestedVrComponent != null;
2281                    requestedPackage = r.requestedVrComponent;
2282                    userId = r.userId;
2283                    callingPackage = r.info.getComponentName();
2284                    if (mInVrMode != vrMode) {
2285                        mInVrMode = vrMode;
2286                        mShowDialogs = shouldShowDialogs(getGlobalConfiguration(), mInVrMode);
2287                        if (r.app != null) {
2288                            ProcessRecord proc = r.app;
2289                            if (proc.vrThreadTid > 0) {
2290                                if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
2291                                    try {
2292                                        if (mInVrMode == true) {
2293                                            Process.setThreadScheduler(proc.vrThreadTid,
2294                                                Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
2295                                        } else {
2296                                            Process.setThreadScheduler(proc.vrThreadTid,
2297                                                Process.SCHED_OTHER, 0);
2298                                        }
2299                                    } catch (IllegalArgumentException e) {
2300                                        Slog.w(TAG, "Failed to set scheduling policy, thread does"
2301                                                + " not exist:\n" + e);
2302                                    }
2303                                }
2304                            }
2305                        }
2306                    }
2307                }
2308                vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2309            } case NOTIFY_VR_SLEEPING_MSG: {
2310                notifyVrManagerOfSleepState(msg.arg1 != 0);
2311            } break;
2312            case HANDLE_TRUST_STORAGE_UPDATE_MSG: {
2313                synchronized (ActivityManagerService.this) {
2314                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2315                        ProcessRecord r = mLruProcesses.get(i);
2316                        if (r.thread != null) {
2317                            try {
2318                                r.thread.handleTrustStorageUpdate();
2319                            } catch (RemoteException ex) {
2320                                Slog.w(TAG, "Failed to handle trust storage update for: " +
2321                                        r.info.processName);
2322                            }
2323                        }
2324                    }
2325                }
2326            } break;
2327            }
2328        }
2329    };
2330
2331    static final int COLLECT_PSS_BG_MSG = 1;
2332
2333    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2334        @Override
2335        public void handleMessage(Message msg) {
2336            switch (msg.what) {
2337            case COLLECT_PSS_BG_MSG: {
2338                long start = SystemClock.uptimeMillis();
2339                MemInfoReader memInfo = null;
2340                synchronized (ActivityManagerService.this) {
2341                    if (mFullPssPending) {
2342                        mFullPssPending = false;
2343                        memInfo = new MemInfoReader();
2344                    }
2345                }
2346                if (memInfo != null) {
2347                    updateCpuStatsNow();
2348                    long nativeTotalPss = 0;
2349                    final List<ProcessCpuTracker.Stats> stats;
2350                    synchronized (mProcessCpuTracker) {
2351                        stats = mProcessCpuTracker.getStats( (st)-> {
2352                            return st.vsize > 0 && st.uid < Process.FIRST_APPLICATION_UID;
2353                        });
2354                    }
2355                    final int N = stats.size();
2356                    for (int j = 0; j < N; j++) {
2357                        synchronized (mPidsSelfLocked) {
2358                            if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
2359                                // This is one of our own processes; skip it.
2360                                continue;
2361                            }
2362                        }
2363                        nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
2364                    }
2365                    memInfo.readMemInfo();
2366                    synchronized (ActivityManagerService.this) {
2367                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2368                                + (SystemClock.uptimeMillis()-start) + "ms");
2369                        final long cachedKb = memInfo.getCachedSizeKb();
2370                        final long freeKb = memInfo.getFreeSizeKb();
2371                        final long zramKb = memInfo.getZramTotalSizeKb();
2372                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2373                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2374                                kernelKb*1024, nativeTotalPss*1024);
2375                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2376                                nativeTotalPss);
2377                    }
2378                }
2379
2380                int num = 0;
2381                long[] tmp = new long[2];
2382                do {
2383                    ProcessRecord proc;
2384                    int procState;
2385                    int pid;
2386                    long lastPssTime;
2387                    synchronized (ActivityManagerService.this) {
2388                        if (mPendingPssProcesses.size() <= 0) {
2389                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2390                                    "Collected PSS of " + num + " processes in "
2391                                    + (SystemClock.uptimeMillis() - start) + "ms");
2392                            mPendingPssProcesses.clear();
2393                            return;
2394                        }
2395                        proc = mPendingPssProcesses.remove(0);
2396                        procState = proc.pssProcState;
2397                        lastPssTime = proc.lastPssTime;
2398                        if (proc.thread != null && procState == proc.setProcState
2399                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2400                                        < SystemClock.uptimeMillis()) {
2401                            pid = proc.pid;
2402                        } else {
2403                            proc = null;
2404                            pid = 0;
2405                        }
2406                    }
2407                    if (proc != null) {
2408                        long pss = Debug.getPss(pid, tmp, null);
2409                        synchronized (ActivityManagerService.this) {
2410                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2411                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2412                                num++;
2413                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2414                                        SystemClock.uptimeMillis());
2415                            }
2416                        }
2417                    }
2418                } while (true);
2419            }
2420            }
2421        }
2422    };
2423
2424    public void setSystemProcess() {
2425        try {
2426            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2427            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2428            ServiceManager.addService("meminfo", new MemBinder(this));
2429            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2430            ServiceManager.addService("dbinfo", new DbBinder(this));
2431            if (MONITOR_CPU_USAGE) {
2432                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2433            }
2434            ServiceManager.addService("permission", new PermissionController(this));
2435            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2436
2437            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2438                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2439            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2440
2441            synchronized (this) {
2442                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2443                app.persistent = true;
2444                app.pid = MY_PID;
2445                app.maxAdj = ProcessList.SYSTEM_ADJ;
2446                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2447                synchronized (mPidsSelfLocked) {
2448                    mPidsSelfLocked.put(app.pid, app);
2449                }
2450                updateLruProcessLocked(app, false, null);
2451                updateOomAdjLocked();
2452            }
2453        } catch (PackageManager.NameNotFoundException e) {
2454            throw new RuntimeException(
2455                    "Unable to find android system package", e);
2456        }
2457    }
2458
2459    public void setWindowManager(WindowManagerService wm) {
2460        mWindowManager = wm;
2461        mStackSupervisor.setWindowManager(wm);
2462        mActivityStarter.setWindowManager(wm);
2463    }
2464
2465    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2466        mUsageStatsService = usageStatsManager;
2467    }
2468
2469    public void startObservingNativeCrashes() {
2470        final NativeCrashListener ncl = new NativeCrashListener(this);
2471        ncl.start();
2472    }
2473
2474    public IAppOpsService getAppOpsService() {
2475        return mAppOpsService;
2476    }
2477
2478    static class MemBinder extends Binder {
2479        ActivityManagerService mActivityManagerService;
2480        MemBinder(ActivityManagerService activityManagerService) {
2481            mActivityManagerService = activityManagerService;
2482        }
2483
2484        @Override
2485        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2486            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2487                    != PackageManager.PERMISSION_GRANTED) {
2488                pw.println("Permission Denial: can't dump meminfo from from pid="
2489                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2490                        + " without permission " + android.Manifest.permission.DUMP);
2491                return;
2492            }
2493
2494            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2495        }
2496    }
2497
2498    static class GraphicsBinder extends Binder {
2499        ActivityManagerService mActivityManagerService;
2500        GraphicsBinder(ActivityManagerService activityManagerService) {
2501            mActivityManagerService = activityManagerService;
2502        }
2503
2504        @Override
2505        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2506            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2507                    != PackageManager.PERMISSION_GRANTED) {
2508                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2509                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2510                        + " without permission " + android.Manifest.permission.DUMP);
2511                return;
2512            }
2513
2514            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2515        }
2516    }
2517
2518    static class DbBinder extends Binder {
2519        ActivityManagerService mActivityManagerService;
2520        DbBinder(ActivityManagerService activityManagerService) {
2521            mActivityManagerService = activityManagerService;
2522        }
2523
2524        @Override
2525        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2526            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2527                    != PackageManager.PERMISSION_GRANTED) {
2528                pw.println("Permission Denial: can't dump dbinfo from from pid="
2529                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2530                        + " without permission " + android.Manifest.permission.DUMP);
2531                return;
2532            }
2533
2534            mActivityManagerService.dumpDbInfo(fd, pw, args);
2535        }
2536    }
2537
2538    static class CpuBinder extends Binder {
2539        ActivityManagerService mActivityManagerService;
2540        CpuBinder(ActivityManagerService activityManagerService) {
2541            mActivityManagerService = activityManagerService;
2542        }
2543
2544        @Override
2545        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2546            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2547                    != PackageManager.PERMISSION_GRANTED) {
2548                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2549                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2550                        + " without permission " + android.Manifest.permission.DUMP);
2551                return;
2552            }
2553
2554            synchronized (mActivityManagerService.mProcessCpuTracker) {
2555                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2556                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2557                        SystemClock.uptimeMillis()));
2558            }
2559        }
2560    }
2561
2562    public static final class Lifecycle extends SystemService {
2563        private final ActivityManagerService mService;
2564
2565        public Lifecycle(Context context) {
2566            super(context);
2567            mService = new ActivityManagerService(context);
2568        }
2569
2570        @Override
2571        public void onStart() {
2572            mService.start();
2573        }
2574
2575        public ActivityManagerService getService() {
2576            return mService;
2577        }
2578    }
2579
2580    // Note: This method is invoked on the main thread but may need to attach various
2581    // handlers to other threads.  So take care to be explicit about the looper.
2582    public ActivityManagerService(Context systemContext) {
2583        mContext = systemContext;
2584        mFactoryTest = FactoryTest.getMode();
2585        mSystemThread = ActivityThread.currentActivityThread();
2586
2587        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2588
2589        mPermissionReviewRequired = mContext.getResources().getBoolean(
2590                com.android.internal.R.bool.config_permissionReviewRequired);
2591
2592        mHandlerThread = new ServiceThread(TAG,
2593                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2594        mHandlerThread.start();
2595        mHandler = new MainHandler(mHandlerThread.getLooper());
2596        mUiHandler = new UiHandler();
2597
2598        /* static; one-time init here */
2599        if (sKillHandler == null) {
2600            sKillThread = new ServiceThread(TAG + ":kill",
2601                    android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2602            sKillThread.start();
2603            sKillHandler = new KillHandler(sKillThread.getLooper());
2604        }
2605
2606        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2607                "foreground", BROADCAST_FG_TIMEOUT, false);
2608        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2609                "background", BROADCAST_BG_TIMEOUT, true);
2610        mBroadcastQueues[0] = mFgBroadcastQueue;
2611        mBroadcastQueues[1] = mBgBroadcastQueue;
2612
2613        mServices = new ActiveServices(this);
2614        mProviderMap = new ProviderMap(this);
2615        mAppErrors = new AppErrors(mContext, this);
2616
2617        // TODO: Move creation of battery stats service outside of activity manager service.
2618        File dataDir = Environment.getDataDirectory();
2619        File systemDir = new File(dataDir, "system");
2620        systemDir.mkdirs();
2621        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2622        mBatteryStatsService.getActiveStatistics().readLocked();
2623        mBatteryStatsService.scheduleWriteToDisk();
2624        mOnBattery = DEBUG_POWER ? true
2625                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2626        mBatteryStatsService.getActiveStatistics().setCallback(this);
2627
2628        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2629
2630        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2631        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2632                new IAppOpsCallback.Stub() {
2633                    @Override public void opChanged(int op, int uid, String packageName) {
2634                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2635                            if (mAppOpsService.checkOperation(op, uid, packageName)
2636                                    != AppOpsManager.MODE_ALLOWED) {
2637                                runInBackgroundDisabled(uid);
2638                            }
2639                        }
2640                    }
2641                });
2642
2643        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2644
2645        mUserController = new UserController(this);
2646
2647        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2648            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2649
2650        if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
2651            mUseFifoUiScheduling = true;
2652        }
2653
2654        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2655        mTempConfig.setToDefaults();
2656        mTempConfig.setLocales(LocaleList.getDefault());
2657        mConfigurationSeq = mTempConfig.seq = 1;
2658        mStackSupervisor = new ActivityStackSupervisor(this);
2659        mStackSupervisor.onConfigurationChanged(mTempConfig);
2660        mKeyguardController = mStackSupervisor.mKeyguardController;
2661        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2662        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2663        mTaskChangeNotificationController =
2664                new TaskChangeNotificationController(this, mStackSupervisor, mHandler);
2665        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2666        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2667
2668        mProcessCpuThread = new Thread("CpuTracker") {
2669            @Override
2670            public void run() {
2671                synchronized (mProcessCpuTracker) {
2672                    mProcessCpuInitLatch.countDown();
2673                    mProcessCpuTracker.init();
2674                }
2675                while (true) {
2676                    try {
2677                        try {
2678                            synchronized(this) {
2679                                final long now = SystemClock.uptimeMillis();
2680                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2681                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2682                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2683                                //        + ", write delay=" + nextWriteDelay);
2684                                if (nextWriteDelay < nextCpuDelay) {
2685                                    nextCpuDelay = nextWriteDelay;
2686                                }
2687                                if (nextCpuDelay > 0) {
2688                                    mProcessCpuMutexFree.set(true);
2689                                    this.wait(nextCpuDelay);
2690                                }
2691                            }
2692                        } catch (InterruptedException e) {
2693                        }
2694                        updateCpuStatsNow();
2695                    } catch (Exception e) {
2696                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2697                    }
2698                }
2699            }
2700        };
2701
2702        Watchdog.getInstance().addMonitor(this);
2703        Watchdog.getInstance().addThread(mHandler);
2704    }
2705
2706    public void setSystemServiceManager(SystemServiceManager mgr) {
2707        mSystemServiceManager = mgr;
2708    }
2709
2710    public void setInstaller(Installer installer) {
2711        mInstaller = installer;
2712    }
2713
2714    private void start() {
2715        Process.removeAllProcessGroups();
2716        mProcessCpuThread.start();
2717
2718        mBatteryStatsService.publish(mContext);
2719        mAppOpsService.publish(mContext);
2720        Slog.d("AppOps", "AppOpsService published");
2721        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2722        // Wait for the synchronized block started in mProcessCpuThread,
2723        // so that any other acccess to mProcessCpuTracker from main thread
2724        // will be blocked during mProcessCpuTracker initialization.
2725        try {
2726            mProcessCpuInitLatch.await();
2727        } catch (InterruptedException e) {
2728            Slog.wtf(TAG, "Interrupted wait during start", e);
2729            Thread.currentThread().interrupt();
2730            throw new IllegalStateException("Interrupted wait during start");
2731        }
2732    }
2733
2734    void onUserStoppedLocked(int userId) {
2735        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2736    }
2737
2738    public void initPowerManagement() {
2739        mStackSupervisor.initPowerManagement();
2740        mBatteryStatsService.initPowerManagement();
2741        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2742        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2743        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2744        mVoiceWakeLock.setReferenceCounted(false);
2745    }
2746
2747    @Override
2748    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2749            throws RemoteException {
2750        if (code == SYSPROPS_TRANSACTION) {
2751            // We need to tell all apps about the system property change.
2752            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2753            synchronized(this) {
2754                final int NP = mProcessNames.getMap().size();
2755                for (int ip=0; ip<NP; ip++) {
2756                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2757                    final int NA = apps.size();
2758                    for (int ia=0; ia<NA; ia++) {
2759                        ProcessRecord app = apps.valueAt(ia);
2760                        if (app.thread != null) {
2761                            procs.add(app.thread.asBinder());
2762                        }
2763                    }
2764                }
2765            }
2766
2767            int N = procs.size();
2768            for (int i=0; i<N; i++) {
2769                Parcel data2 = Parcel.obtain();
2770                try {
2771                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null,
2772                            Binder.FLAG_ONEWAY);
2773                } catch (RemoteException e) {
2774                }
2775                data2.recycle();
2776            }
2777        }
2778        try {
2779            return super.onTransact(code, data, reply, flags);
2780        } catch (RuntimeException e) {
2781            // The activity manager only throws security exceptions, so let's
2782            // log all others.
2783            if (!(e instanceof SecurityException)) {
2784                Slog.wtf(TAG, "Activity Manager Crash", e);
2785            }
2786            throw e;
2787        }
2788    }
2789
2790    void updateCpuStats() {
2791        final long now = SystemClock.uptimeMillis();
2792        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2793            return;
2794        }
2795        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2796            synchronized (mProcessCpuThread) {
2797                mProcessCpuThread.notify();
2798            }
2799        }
2800    }
2801
2802    void updateCpuStatsNow() {
2803        synchronized (mProcessCpuTracker) {
2804            mProcessCpuMutexFree.set(false);
2805            final long now = SystemClock.uptimeMillis();
2806            boolean haveNewCpuStats = false;
2807
2808            if (MONITOR_CPU_USAGE &&
2809                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2810                mLastCpuTime.set(now);
2811                mProcessCpuTracker.update();
2812                if (mProcessCpuTracker.hasGoodLastStats()) {
2813                    haveNewCpuStats = true;
2814                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2815                    //Slog.i(TAG, "Total CPU usage: "
2816                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2817
2818                    // Slog the cpu usage if the property is set.
2819                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2820                        int user = mProcessCpuTracker.getLastUserTime();
2821                        int system = mProcessCpuTracker.getLastSystemTime();
2822                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2823                        int irq = mProcessCpuTracker.getLastIrqTime();
2824                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2825                        int idle = mProcessCpuTracker.getLastIdleTime();
2826
2827                        int total = user + system + iowait + irq + softIrq + idle;
2828                        if (total == 0) total = 1;
2829
2830                        EventLog.writeEvent(EventLogTags.CPU,
2831                                ((user+system+iowait+irq+softIrq) * 100) / total,
2832                                (user * 100) / total,
2833                                (system * 100) / total,
2834                                (iowait * 100) / total,
2835                                (irq * 100) / total,
2836                                (softIrq * 100) / total);
2837                    }
2838                }
2839            }
2840
2841            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2842            synchronized(bstats) {
2843                synchronized(mPidsSelfLocked) {
2844                    if (haveNewCpuStats) {
2845                        if (bstats.startAddingCpuLocked()) {
2846                            int totalUTime = 0;
2847                            int totalSTime = 0;
2848                            final int N = mProcessCpuTracker.countStats();
2849                            for (int i=0; i<N; i++) {
2850                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2851                                if (!st.working) {
2852                                    continue;
2853                                }
2854                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2855                                totalUTime += st.rel_utime;
2856                                totalSTime += st.rel_stime;
2857                                if (pr != null) {
2858                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2859                                    if (ps == null || !ps.isActive()) {
2860                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2861                                                pr.info.uid, pr.processName);
2862                                    }
2863                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2864                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2865                                } else {
2866                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2867                                    if (ps == null || !ps.isActive()) {
2868                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2869                                                bstats.mapUid(st.uid), st.name);
2870                                    }
2871                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2872                                }
2873                            }
2874                            final int userTime = mProcessCpuTracker.getLastUserTime();
2875                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2876                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2877                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2878                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2879                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2880                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2881                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2882                        }
2883                    }
2884                }
2885
2886                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2887                    mLastWriteTime = now;
2888                    mBatteryStatsService.scheduleWriteToDisk();
2889                }
2890            }
2891        }
2892    }
2893
2894    @Override
2895    public void batteryNeedsCpuUpdate() {
2896        updateCpuStatsNow();
2897    }
2898
2899    @Override
2900    public void batteryPowerChanged(boolean onBattery) {
2901        // When plugging in, update the CPU stats first before changing
2902        // the plug state.
2903        updateCpuStatsNow();
2904        synchronized (this) {
2905            synchronized(mPidsSelfLocked) {
2906                mOnBattery = DEBUG_POWER ? true : onBattery;
2907            }
2908        }
2909    }
2910
2911    @Override
2912    public void batterySendBroadcast(Intent intent) {
2913        synchronized (this) {
2914            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2915                    AppOpsManager.OP_NONE, null, false, false,
2916                    -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2917        }
2918    }
2919
2920    /**
2921     * Initialize the application bind args. These are passed to each
2922     * process when the bindApplication() IPC is sent to the process. They're
2923     * lazily setup to make sure the services are running when they're asked for.
2924     */
2925    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2926        // Isolated processes won't get this optimization, so that we don't
2927        // violate the rules about which services they have access to.
2928        if (isolated) {
2929            if (mIsolatedAppBindArgs == null) {
2930                mIsolatedAppBindArgs = new HashMap<>();
2931                mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
2932            }
2933            return mIsolatedAppBindArgs;
2934        }
2935
2936        if (mAppBindArgs == null) {
2937            mAppBindArgs = new HashMap<>();
2938
2939            // Setup the application init args
2940            mAppBindArgs.put("package", ServiceManager.getService("package"));
2941            mAppBindArgs.put("window", ServiceManager.getService("window"));
2942            mAppBindArgs.put(Context.ALARM_SERVICE,
2943                    ServiceManager.getService(Context.ALARM_SERVICE));
2944        }
2945        return mAppBindArgs;
2946    }
2947
2948    /**
2949     * Update AMS states when an activity is resumed. This should only be called by
2950     * {@link ActivityStack#setResumedActivityLocked} when an activity is resumed.
2951     */
2952    void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
2953        if (r.task.isApplicationTask()) {
2954            if (mCurAppTimeTracker != r.appTimeTracker) {
2955                // We are switching app tracking.  Complete the current one.
2956                if (mCurAppTimeTracker != null) {
2957                    mCurAppTimeTracker.stop();
2958                    mHandler.obtainMessage(
2959                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2960                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2961                    mCurAppTimeTracker = null;
2962                }
2963                if (r.appTimeTracker != null) {
2964                    mCurAppTimeTracker = r.appTimeTracker;
2965                    startTimeTrackingFocusedActivityLocked();
2966                }
2967            } else {
2968                startTimeTrackingFocusedActivityLocked();
2969            }
2970        } else {
2971            r.appTimeTracker = null;
2972        }
2973        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2974        // TODO: Probably not, because we don't want to resume voice on switching
2975        // back to this activity
2976        if (r.task.voiceInteractor != null) {
2977            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2978        } else {
2979            finishRunningVoiceLocked();
2980            IVoiceInteractionSession session;
2981            if (mLastResumedActivity != null
2982                    && ((session = mLastResumedActivity.task.voiceSession) != null
2983                    || (session = mLastResumedActivity.voiceSession) != null)) {
2984                // We had been in a voice interaction session, but now focused has
2985                // move to something different.  Just finish the session, we can't
2986                // return to it and retain the proper state and synchronization with
2987                // the voice interaction service.
2988                finishVoiceTask(session);
2989            }
2990        }
2991
2992        mWindowManager.setFocusedApp(r.appToken, true);
2993
2994        applyUpdateLockStateLocked(r);
2995        applyUpdateVrModeLocked(r);
2996        if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
2997            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2998            mHandler.obtainMessage(
2999                    FOREGROUND_PROFILE_CHANGED_MSG, r.userId, 0).sendToTarget();
3000        }
3001
3002        mLastResumedActivity = r;
3003
3004        EventLogTags.writeAmSetResumedActivity(
3005                r == null ? -1 : r.userId,
3006                r == null ? "NULL" : r.shortComponentName,
3007                reason);
3008    }
3009
3010    @Override
3011    public void setFocusedStack(int stackId) {
3012        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3013        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3014        final long callingId = Binder.clearCallingIdentity();
3015        try {
3016            synchronized (this) {
3017                final ActivityStack stack = mStackSupervisor.getStack(stackId);
3018                if (stack == null) {
3019                    return;
3020                }
3021                final ActivityRecord r = stack.topRunningActivityLocked();
3022                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedStack")) {
3023                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3024                }
3025            }
3026        } finally {
3027            Binder.restoreCallingIdentity(callingId);
3028        }
3029    }
3030
3031    @Override
3032    public void setFocusedTask(int taskId) {
3033        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3034        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3035        final long callingId = Binder.clearCallingIdentity();
3036        try {
3037            synchronized (this) {
3038                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3039                if (task == null) {
3040                    return;
3041                }
3042                final ActivityRecord r = task.topRunningActivityLocked();
3043                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
3044                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3045                }
3046            }
3047        } finally {
3048            Binder.restoreCallingIdentity(callingId);
3049        }
3050    }
3051
3052    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3053    @Override
3054    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3055        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3056        mTaskChangeNotificationController.registerTaskStackListener(listener);
3057    }
3058
3059    /**
3060     * Unregister a task stack listener so that it stops receiving callbacks.
3061     */
3062    @Override
3063    public void unregisterTaskStackListener(ITaskStackListener listener) throws RemoteException {
3064         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "unregisterTaskStackListener()");
3065         mTaskChangeNotificationController.unregisterTaskStackListener(listener);
3066     }
3067
3068    @Override
3069    public void notifyActivityDrawn(IBinder token) {
3070        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3071        synchronized (this) {
3072            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3073            if (r != null) {
3074                r.getStack().notifyActivityDrawnLocked(r);
3075            }
3076        }
3077    }
3078
3079    final void applyUpdateLockStateLocked(ActivityRecord r) {
3080        // Modifications to the UpdateLock state are done on our handler, outside
3081        // the activity manager's locks.  The new state is determined based on the
3082        // state *now* of the relevant activity record.  The object is passed to
3083        // the handler solely for logging detail, not to be consulted/modified.
3084        final boolean nextState = r != null && r.immersive;
3085        mHandler.sendMessage(
3086                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3087    }
3088
3089    final void applyUpdateVrModeLocked(ActivityRecord r) {
3090        mHandler.sendMessage(
3091                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3092    }
3093
3094    private void sendNotifyVrManagerOfSleepState(boolean isSleeping) {
3095        mHandler.sendMessage(
3096                mHandler.obtainMessage(NOTIFY_VR_SLEEPING_MSG, isSleeping ? 1 : 0, 0));
3097    }
3098
3099    private void notifyVrManagerOfSleepState(boolean isSleeping) {
3100        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
3101        if (vrService == null) {
3102            return;
3103        }
3104        vrService.onSleepStateChanged(isSleeping);
3105    }
3106
3107    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3108        Message msg = Message.obtain();
3109        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3110        msg.obj = r.task.askedCompatMode ? null : r;
3111        mUiHandler.sendMessage(msg);
3112    }
3113
3114    final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3115        final Configuration globalConfig = getGlobalConfiguration();
3116        if (globalConfig.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3117                && r.appInfo.requiresSmallestWidthDp > globalConfig.smallestScreenWidthDp) {
3118            final Message msg = Message.obtain();
3119            msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3120            msg.obj = r;
3121            mUiHandler.sendMessage(msg);
3122        }
3123    }
3124
3125    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3126            String what, Object obj, ProcessRecord srcApp) {
3127        app.lastActivityTime = now;
3128
3129        if (app.activities.size() > 0) {
3130            // Don't want to touch dependent processes that are hosting activities.
3131            return index;
3132        }
3133
3134        int lrui = mLruProcesses.lastIndexOf(app);
3135        if (lrui < 0) {
3136            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3137                    + what + " " + obj + " from " + srcApp);
3138            return index;
3139        }
3140
3141        if (lrui >= index) {
3142            // Don't want to cause this to move dependent processes *back* in the
3143            // list as if they were less frequently used.
3144            return index;
3145        }
3146
3147        if (lrui >= mLruProcessActivityStart) {
3148            // Don't want to touch dependent processes that are hosting activities.
3149            return index;
3150        }
3151
3152        mLruProcesses.remove(lrui);
3153        if (index > 0) {
3154            index--;
3155        }
3156        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3157                + " in LRU list: " + app);
3158        mLruProcesses.add(index, app);
3159        return index;
3160    }
3161
3162    static void killProcessGroup(int uid, int pid) {
3163        if (sKillHandler != null) {
3164            sKillHandler.sendMessage(
3165                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3166        } else {
3167            Slog.w(TAG, "Asked to kill process group before system bringup!");
3168            Process.killProcessGroup(uid, pid);
3169        }
3170    }
3171
3172    final void removeLruProcessLocked(ProcessRecord app) {
3173        int lrui = mLruProcesses.lastIndexOf(app);
3174        if (lrui >= 0) {
3175            if (!app.killed) {
3176                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3177                Process.killProcessQuiet(app.pid);
3178                killProcessGroup(app.uid, app.pid);
3179            }
3180            if (lrui <= mLruProcessActivityStart) {
3181                mLruProcessActivityStart--;
3182            }
3183            if (lrui <= mLruProcessServiceStart) {
3184                mLruProcessServiceStart--;
3185            }
3186            mLruProcesses.remove(lrui);
3187        }
3188    }
3189
3190    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3191            ProcessRecord client) {
3192        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3193                || app.treatLikeActivity;
3194        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3195        if (!activityChange && hasActivity) {
3196            // The process has activities, so we are only allowing activity-based adjustments
3197            // to move it.  It should be kept in the front of the list with other
3198            // processes that have activities, and we don't want those to change their
3199            // order except due to activity operations.
3200            return;
3201        }
3202
3203        mLruSeq++;
3204        final long now = SystemClock.uptimeMillis();
3205        app.lastActivityTime = now;
3206
3207        // First a quick reject: if the app is already at the position we will
3208        // put it, then there is nothing to do.
3209        if (hasActivity) {
3210            final int N = mLruProcesses.size();
3211            if (N > 0 && mLruProcesses.get(N-1) == app) {
3212                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3213                return;
3214            }
3215        } else {
3216            if (mLruProcessServiceStart > 0
3217                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3218                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3219                return;
3220            }
3221        }
3222
3223        int lrui = mLruProcesses.lastIndexOf(app);
3224
3225        if (app.persistent && lrui >= 0) {
3226            // We don't care about the position of persistent processes, as long as
3227            // they are in the list.
3228            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3229            return;
3230        }
3231
3232        /* In progress: compute new position first, so we can avoid doing work
3233           if the process is not actually going to move.  Not yet working.
3234        int addIndex;
3235        int nextIndex;
3236        boolean inActivity = false, inService = false;
3237        if (hasActivity) {
3238            // Process has activities, put it at the very tipsy-top.
3239            addIndex = mLruProcesses.size();
3240            nextIndex = mLruProcessServiceStart;
3241            inActivity = true;
3242        } else if (hasService) {
3243            // Process has services, put it at the top of the service list.
3244            addIndex = mLruProcessActivityStart;
3245            nextIndex = mLruProcessServiceStart;
3246            inActivity = true;
3247            inService = true;
3248        } else  {
3249            // Process not otherwise of interest, it goes to the top of the non-service area.
3250            addIndex = mLruProcessServiceStart;
3251            if (client != null) {
3252                int clientIndex = mLruProcesses.lastIndexOf(client);
3253                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3254                        + app);
3255                if (clientIndex >= 0 && addIndex > clientIndex) {
3256                    addIndex = clientIndex;
3257                }
3258            }
3259            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3260        }
3261
3262        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3263                + mLruProcessActivityStart + "): " + app);
3264        */
3265
3266        if (lrui >= 0) {
3267            if (lrui < mLruProcessActivityStart) {
3268                mLruProcessActivityStart--;
3269            }
3270            if (lrui < mLruProcessServiceStart) {
3271                mLruProcessServiceStart--;
3272            }
3273            /*
3274            if (addIndex > lrui) {
3275                addIndex--;
3276            }
3277            if (nextIndex > lrui) {
3278                nextIndex--;
3279            }
3280            */
3281            mLruProcesses.remove(lrui);
3282        }
3283
3284        /*
3285        mLruProcesses.add(addIndex, app);
3286        if (inActivity) {
3287            mLruProcessActivityStart++;
3288        }
3289        if (inService) {
3290            mLruProcessActivityStart++;
3291        }
3292        */
3293
3294        int nextIndex;
3295        if (hasActivity) {
3296            final int N = mLruProcesses.size();
3297            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3298                // Process doesn't have activities, but has clients with
3299                // activities...  move it up, but one below the top (the top
3300                // should always have a real activity).
3301                if (DEBUG_LRU) Slog.d(TAG_LRU,
3302                        "Adding to second-top of LRU activity list: " + app);
3303                mLruProcesses.add(N - 1, app);
3304                // To keep it from spamming the LRU list (by making a bunch of clients),
3305                // we will push down any other entries owned by the app.
3306                final int uid = app.info.uid;
3307                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3308                    ProcessRecord subProc = mLruProcesses.get(i);
3309                    if (subProc.info.uid == uid) {
3310                        // We want to push this one down the list.  If the process after
3311                        // it is for the same uid, however, don't do so, because we don't
3312                        // want them internally to be re-ordered.
3313                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3314                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3315                                    "Pushing uid " + uid + " swapping at " + i + ": "
3316                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3317                            ProcessRecord tmp = mLruProcesses.get(i);
3318                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3319                            mLruProcesses.set(i - 1, tmp);
3320                            i--;
3321                        }
3322                    } else {
3323                        // A gap, we can stop here.
3324                        break;
3325                    }
3326                }
3327            } else {
3328                // Process has activities, put it at the very tipsy-top.
3329                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3330                mLruProcesses.add(app);
3331            }
3332            nextIndex = mLruProcessServiceStart;
3333        } else if (hasService) {
3334            // Process has services, put it at the top of the service list.
3335            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3336            mLruProcesses.add(mLruProcessActivityStart, app);
3337            nextIndex = mLruProcessServiceStart;
3338            mLruProcessActivityStart++;
3339        } else  {
3340            // Process not otherwise of interest, it goes to the top of the non-service area.
3341            int index = mLruProcessServiceStart;
3342            if (client != null) {
3343                // If there is a client, don't allow the process to be moved up higher
3344                // in the list than that client.
3345                int clientIndex = mLruProcesses.lastIndexOf(client);
3346                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3347                        + " when updating " + app);
3348                if (clientIndex <= lrui) {
3349                    // Don't allow the client index restriction to push it down farther in the
3350                    // list than it already is.
3351                    clientIndex = lrui;
3352                }
3353                if (clientIndex >= 0 && index > clientIndex) {
3354                    index = clientIndex;
3355                }
3356            }
3357            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3358            mLruProcesses.add(index, app);
3359            nextIndex = index-1;
3360            mLruProcessActivityStart++;
3361            mLruProcessServiceStart++;
3362        }
3363
3364        // If the app is currently using a content provider or service,
3365        // bump those processes as well.
3366        for (int j=app.connections.size()-1; j>=0; j--) {
3367            ConnectionRecord cr = app.connections.valueAt(j);
3368            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3369                    && cr.binding.service.app != null
3370                    && cr.binding.service.app.lruSeq != mLruSeq
3371                    && !cr.binding.service.app.persistent) {
3372                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3373                        "service connection", cr, app);
3374            }
3375        }
3376        for (int j=app.conProviders.size()-1; j>=0; j--) {
3377            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3378            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3379                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3380                        "provider reference", cpr, app);
3381            }
3382        }
3383    }
3384
3385    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3386        if (uid == Process.SYSTEM_UID) {
3387            // The system gets to run in any process.  If there are multiple
3388            // processes with the same uid, just pick the first (this
3389            // should never happen).
3390            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3391            if (procs == null) return null;
3392            final int procCount = procs.size();
3393            for (int i = 0; i < procCount; i++) {
3394                final int procUid = procs.keyAt(i);
3395                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3396                    // Don't use an app process or different user process for system component.
3397                    continue;
3398                }
3399                return procs.valueAt(i);
3400            }
3401        }
3402        ProcessRecord proc = mProcessNames.get(processName, uid);
3403        if (false && proc != null && !keepIfLarge
3404                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3405                && proc.lastCachedPss >= 4000) {
3406            // Turn this condition on to cause killing to happen regularly, for testing.
3407            if (proc.baseProcessTracker != null) {
3408                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3409            }
3410            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3411        } else if (proc != null && !keepIfLarge
3412                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3413                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3414            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3415            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3416                if (proc.baseProcessTracker != null) {
3417                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3418                }
3419                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3420            }
3421        }
3422        return proc;
3423    }
3424
3425    void notifyPackageUse(String packageName, int reason) {
3426        IPackageManager pm = AppGlobals.getPackageManager();
3427        try {
3428            pm.notifyPackageUse(packageName, reason);
3429        } catch (RemoteException e) {
3430        }
3431    }
3432
3433    boolean isNextTransitionForward() {
3434        int transit = mWindowManager.getPendingAppTransition();
3435        return transit == TRANSIT_ACTIVITY_OPEN
3436                || transit == TRANSIT_TASK_OPEN
3437                || transit == TRANSIT_TASK_TO_FRONT;
3438    }
3439
3440    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3441            String processName, String abiOverride, int uid, Runnable crashHandler) {
3442        synchronized(this) {
3443            ApplicationInfo info = new ApplicationInfo();
3444            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3445            // For isolated processes, the former contains the parent's uid and the latter the
3446            // actual uid of the isolated process.
3447            // In the special case introduced by this method (which is, starting an isolated
3448            // process directly from the SystemServer without an actual parent app process) the
3449            // closest thing to a parent's uid is SYSTEM_UID.
3450            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3451            // the |isolated| logic in the ProcessRecord constructor.
3452            info.uid = Process.SYSTEM_UID;
3453            info.processName = processName;
3454            info.className = entryPoint;
3455            info.packageName = "android";
3456            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3457                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3458                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3459                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3460                    crashHandler);
3461            return proc != null ? proc.pid : 0;
3462        }
3463    }
3464
3465    final ProcessRecord startProcessLocked(String processName,
3466            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3467            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3468            boolean isolated, boolean keepIfLarge) {
3469        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3470                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3471                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3472                null /* crashHandler */);
3473    }
3474
3475    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3476            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3477            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3478            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3479        long startTime = SystemClock.elapsedRealtime();
3480        ProcessRecord app;
3481        if (!isolated) {
3482            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3483            checkTime(startTime, "startProcess: after getProcessRecord");
3484
3485            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3486                // If we are in the background, then check to see if this process
3487                // is bad.  If so, we will just silently fail.
3488                if (mAppErrors.isBadProcessLocked(info)) {
3489                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3490                            + "/" + info.processName);
3491                    return null;
3492                }
3493            } else {
3494                // When the user is explicitly starting a process, then clear its
3495                // crash count so that we won't make it bad until they see at
3496                // least one crash dialog again, and make the process good again
3497                // if it had been bad.
3498                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3499                        + "/" + info.processName);
3500                mAppErrors.resetProcessCrashTimeLocked(info);
3501                if (mAppErrors.isBadProcessLocked(info)) {
3502                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3503                            UserHandle.getUserId(info.uid), info.uid,
3504                            info.processName);
3505                    mAppErrors.clearBadProcessLocked(info);
3506                    if (app != null) {
3507                        app.bad = false;
3508                    }
3509                }
3510            }
3511        } else {
3512            // If this is an isolated process, it can't re-use an existing process.
3513            app = null;
3514        }
3515
3516        // We don't have to do anything more if:
3517        // (1) There is an existing application record; and
3518        // (2) The caller doesn't think it is dead, OR there is no thread
3519        //     object attached to it so we know it couldn't have crashed; and
3520        // (3) There is a pid assigned to it, so it is either starting or
3521        //     already running.
3522        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3523                + " app=" + app + " knownToBeDead=" + knownToBeDead
3524                + " thread=" + (app != null ? app.thread : null)
3525                + " pid=" + (app != null ? app.pid : -1));
3526        if (app != null && app.pid > 0) {
3527            if ((!knownToBeDead && !app.killed) || app.thread == null) {
3528                // We already have the app running, or are waiting for it to
3529                // come up (we have a pid but not yet its thread), so keep it.
3530                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3531                // If this is a new package in the process, add the package to the list
3532                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3533                checkTime(startTime, "startProcess: done, added package to proc");
3534                return app;
3535            }
3536
3537            // An application record is attached to a previous process,
3538            // clean it up now.
3539            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3540            checkTime(startTime, "startProcess: bad proc running, killing");
3541            killProcessGroup(app.uid, app.pid);
3542            handleAppDiedLocked(app, true, true);
3543            checkTime(startTime, "startProcess: done killing old proc");
3544        }
3545
3546        String hostingNameStr = hostingName != null
3547                ? hostingName.flattenToShortString() : null;
3548
3549        if (app == null) {
3550            checkTime(startTime, "startProcess: creating new process record");
3551            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3552            if (app == null) {
3553                Slog.w(TAG, "Failed making new process record for "
3554                        + processName + "/" + info.uid + " isolated=" + isolated);
3555                return null;
3556            }
3557            app.crashHandler = crashHandler;
3558            checkTime(startTime, "startProcess: done creating new process record");
3559        } else {
3560            // If this is a new package in the process, add the package to the list
3561            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3562            checkTime(startTime, "startProcess: added package to existing proc");
3563        }
3564
3565        // If the system is not ready yet, then hold off on starting this
3566        // process until it is.
3567        if (!mProcessesReady
3568                && !isAllowedWhileBooting(info)
3569                && !allowWhileBooting) {
3570            if (!mProcessesOnHold.contains(app)) {
3571                mProcessesOnHold.add(app);
3572            }
3573            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3574                    "System not ready, putting on hold: " + app);
3575            checkTime(startTime, "startProcess: returning with proc on hold");
3576            return app;
3577        }
3578
3579        checkTime(startTime, "startProcess: stepping in to startProcess");
3580        startProcessLocked(
3581                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3582        checkTime(startTime, "startProcess: done starting proc!");
3583        return (app.pid != 0) ? app : null;
3584    }
3585
3586    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3587        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3588    }
3589
3590    private final void startProcessLocked(ProcessRecord app,
3591            String hostingType, String hostingNameStr) {
3592        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3593                null /* entryPoint */, null /* entryPointArgs */);
3594    }
3595
3596    private final void startProcessLocked(ProcessRecord app, String hostingType,
3597            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3598        long startTime = SystemClock.elapsedRealtime();
3599        if (app.pid > 0 && app.pid != MY_PID) {
3600            checkTime(startTime, "startProcess: removing from pids map");
3601            synchronized (mPidsSelfLocked) {
3602                mPidsSelfLocked.remove(app.pid);
3603                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3604            }
3605            checkTime(startTime, "startProcess: done removing from pids map");
3606            app.setPid(0);
3607        }
3608
3609        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3610                "startProcessLocked removing on hold: " + app);
3611        mProcessesOnHold.remove(app);
3612
3613        checkTime(startTime, "startProcess: starting to update cpu stats");
3614        updateCpuStats();
3615        checkTime(startTime, "startProcess: done updating cpu stats");
3616
3617        try {
3618            try {
3619                final int userId = UserHandle.getUserId(app.uid);
3620                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3621            } catch (RemoteException e) {
3622                throw e.rethrowAsRuntimeException();
3623            }
3624
3625            int uid = app.uid;
3626            int[] gids = null;
3627            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3628            if (!app.isolated) {
3629                int[] permGids = null;
3630                try {
3631                    checkTime(startTime, "startProcess: getting gids from package manager");
3632                    final IPackageManager pm = AppGlobals.getPackageManager();
3633                    permGids = pm.getPackageGids(app.info.packageName,
3634                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3635                    StorageManagerInternal storageManagerInternal = LocalServices.getService(
3636                            StorageManagerInternal.class);
3637                    mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
3638                            app.info.packageName);
3639                } catch (RemoteException e) {
3640                    throw e.rethrowAsRuntimeException();
3641                }
3642
3643                /*
3644                 * Add shared application and profile GIDs so applications can share some
3645                 * resources like shared libraries and access user-wide resources
3646                 */
3647                if (ArrayUtils.isEmpty(permGids)) {
3648                    gids = new int[3];
3649                } else {
3650                    gids = new int[permGids.length + 3];
3651                    System.arraycopy(permGids, 0, gids, 3, permGids.length);
3652                }
3653                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3654                gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
3655                gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3656            }
3657            checkTime(startTime, "startProcess: building args");
3658            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3659                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3660                        && mTopComponent != null
3661                        && app.processName.equals(mTopComponent.getPackageName())) {
3662                    uid = 0;
3663                }
3664                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3665                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3666                    uid = 0;
3667                }
3668            }
3669            int debugFlags = 0;
3670            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3671                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3672                // Also turn on CheckJNI for debuggable apps. It's quite
3673                // awkward to turn on otherwise.
3674                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3675            }
3676            // Run the app in safe mode if its manifest requests so or the
3677            // system is booted in safe mode.
3678            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3679                mSafeMode == true) {
3680                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3681            }
3682            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3683                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3684            }
3685            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3686            if ("true".equals(genDebugInfoProperty)) {
3687                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3688            }
3689            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3690                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3691            }
3692            if ("1".equals(SystemProperties.get("debug.assert"))) {
3693                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3694            }
3695            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3696                // Enable all debug flags required by the native debugger.
3697                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3698                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3699                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3700                mNativeDebuggingApp = null;
3701            }
3702
3703            String invokeWith = null;
3704            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3705                // Debuggable apps may include a wrapper script with their library directory.
3706                String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
3707                if (new File(wrapperFileName).exists()) {
3708                    invokeWith = "/system/bin/logwrapper " + wrapperFileName;
3709                }
3710            }
3711
3712            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3713            if (requiredAbi == null) {
3714                requiredAbi = Build.SUPPORTED_ABIS[0];
3715            }
3716
3717            String instructionSet = null;
3718            if (app.info.primaryCpuAbi != null) {
3719                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3720            }
3721
3722            app.gids = gids;
3723            app.requiredAbi = requiredAbi;
3724            app.instructionSet = instructionSet;
3725
3726            // Start the process.  It will either succeed and return a result containing
3727            // the PID of the new process, or else throw a RuntimeException.
3728            boolean isActivityProcess = (entryPoint == null);
3729            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3730            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3731                    app.processName);
3732            checkTime(startTime, "startProcess: asking zygote to start proc");
3733            Process.ProcessStartResult startResult;
3734            if (hostingType.equals("webview_service")) {
3735                startResult = Process.startWebView(entryPoint,
3736                        app.processName, uid, uid, gids, debugFlags, mountExternal,
3737                        app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3738                        app.info.dataDir, null, entryPointArgs);
3739            } else {
3740                startResult = Process.start(entryPoint,
3741                        app.processName, uid, uid, gids, debugFlags, mountExternal,
3742                        app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3743                        app.info.dataDir, invokeWith, entryPointArgs);
3744            }
3745            checkTime(startTime, "startProcess: returned from zygote!");
3746            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3747
3748            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3749            checkTime(startTime, "startProcess: done updating battery stats");
3750
3751            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3752                    UserHandle.getUserId(uid), startResult.pid, uid,
3753                    app.processName, hostingType,
3754                    hostingNameStr != null ? hostingNameStr : "");
3755
3756            try {
3757                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3758                        app.info.seinfo, app.info.sourceDir, startResult.pid);
3759            } catch (RemoteException ex) {
3760                // Ignore
3761            }
3762
3763            if (app.persistent) {
3764                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3765            }
3766
3767            checkTime(startTime, "startProcess: building log message");
3768            StringBuilder buf = mStringBuilder;
3769            buf.setLength(0);
3770            buf.append("Start proc ");
3771            buf.append(startResult.pid);
3772            buf.append(':');
3773            buf.append(app.processName);
3774            buf.append('/');
3775            UserHandle.formatUid(buf, uid);
3776            if (!isActivityProcess) {
3777                buf.append(" [");
3778                buf.append(entryPoint);
3779                buf.append("]");
3780            }
3781            buf.append(" for ");
3782            buf.append(hostingType);
3783            if (hostingNameStr != null) {
3784                buf.append(" ");
3785                buf.append(hostingNameStr);
3786            }
3787            Slog.i(TAG, buf.toString());
3788            app.setPid(startResult.pid);
3789            app.usingWrapper = startResult.usingWrapper;
3790            app.removed = false;
3791            app.killed = false;
3792            app.killedByAm = false;
3793            checkTime(startTime, "startProcess: starting to update pids map");
3794            ProcessRecord oldApp;
3795            synchronized (mPidsSelfLocked) {
3796                oldApp = mPidsSelfLocked.get(startResult.pid);
3797            }
3798            // If there is already an app occupying that pid that hasn't been cleaned up
3799            if (oldApp != null && !app.isolated) {
3800                // Clean up anything relating to this pid first
3801                Slog.w(TAG, "Reusing pid " + startResult.pid
3802                        + " while app is still mapped to it");
3803                cleanUpApplicationRecordLocked(oldApp, false, false, -1,
3804                        true /*replacingPid*/);
3805            }
3806            synchronized (mPidsSelfLocked) {
3807                this.mPidsSelfLocked.put(startResult.pid, app);
3808                if (isActivityProcess) {
3809                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3810                    msg.obj = app;
3811                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3812                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3813                }
3814            }
3815            checkTime(startTime, "startProcess: done updating pids map");
3816        } catch (RuntimeException e) {
3817            Slog.e(TAG, "Failure starting process " + app.processName, e);
3818
3819            // Something went very wrong while trying to start this process; one
3820            // common case is when the package is frozen due to an active
3821            // upgrade. To recover, clean up any active bookkeeping related to
3822            // starting this process. (We already invoked this method once when
3823            // the package was initially frozen through KILL_APPLICATION_MSG, so
3824            // it doesn't hurt to use it again.)
3825            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3826                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3827        }
3828    }
3829
3830    void updateUsageStats(ActivityRecord component, boolean resumed) {
3831        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3832                "updateUsageStats: comp=" + component + "res=" + resumed);
3833        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3834        if (resumed) {
3835            if (mUsageStatsService != null) {
3836                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3837                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3838            }
3839            synchronized (stats) {
3840                stats.noteActivityResumedLocked(component.app.uid);
3841            }
3842        } else {
3843            if (mUsageStatsService != null) {
3844                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3845                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3846            }
3847            synchronized (stats) {
3848                stats.noteActivityPausedLocked(component.app.uid);
3849            }
3850        }
3851    }
3852
3853    Intent getHomeIntent() {
3854        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3855        intent.setComponent(mTopComponent);
3856        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3857        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3858            intent.addCategory(Intent.CATEGORY_HOME);
3859        }
3860        return intent;
3861    }
3862
3863    boolean startHomeActivityLocked(int userId, String reason) {
3864        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3865                && mTopAction == null) {
3866            // We are running in factory test mode, but unable to find
3867            // the factory test app, so just sit around displaying the
3868            // error message and don't try to start anything.
3869            return false;
3870        }
3871        Intent intent = getHomeIntent();
3872        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3873        if (aInfo != null) {
3874            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3875            // Don't do this if the home app is currently being
3876            // instrumented.
3877            aInfo = new ActivityInfo(aInfo);
3878            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3879            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3880                    aInfo.applicationInfo.uid, true);
3881            if (app == null || app.instrumentationClass == null) {
3882                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3883                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3884            }
3885        } else {
3886            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3887        }
3888
3889        return true;
3890    }
3891
3892    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3893        ActivityInfo ai = null;
3894        ComponentName comp = intent.getComponent();
3895        try {
3896            if (comp != null) {
3897                // Factory test.
3898                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3899            } else {
3900                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3901                        intent,
3902                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3903                        flags, userId);
3904
3905                if (info != null) {
3906                    ai = info.activityInfo;
3907                }
3908            }
3909        } catch (RemoteException e) {
3910            // ignore
3911        }
3912
3913        return ai;
3914    }
3915
3916    /**
3917     * Starts the "new version setup screen" if appropriate.
3918     */
3919    void startSetupActivityLocked() {
3920        // Only do this once per boot.
3921        if (mCheckedForSetup) {
3922            return;
3923        }
3924
3925        // We will show this screen if the current one is a different
3926        // version than the last one shown, and we are not running in
3927        // low-level factory test mode.
3928        final ContentResolver resolver = mContext.getContentResolver();
3929        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3930                Settings.Global.getInt(resolver,
3931                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3932            mCheckedForSetup = true;
3933
3934            // See if we should be showing the platform update setup UI.
3935            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3936            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3937                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3938            if (!ris.isEmpty()) {
3939                final ResolveInfo ri = ris.get(0);
3940                String vers = ri.activityInfo.metaData != null
3941                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3942                        : null;
3943                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3944                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3945                            Intent.METADATA_SETUP_VERSION);
3946                }
3947                String lastVers = Settings.Secure.getString(
3948                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3949                if (vers != null && !vers.equals(lastVers)) {
3950                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3951                    intent.setComponent(new ComponentName(
3952                            ri.activityInfo.packageName, ri.activityInfo.name));
3953                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3954                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3955                            null, 0, 0, 0, null, false, false, null, null, null);
3956                }
3957            }
3958        }
3959    }
3960
3961    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3962        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3963    }
3964
3965    void enforceNotIsolatedCaller(String caller) {
3966        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3967            throw new SecurityException("Isolated process not allowed to call " + caller);
3968        }
3969    }
3970
3971    void enforceShellRestriction(String restriction, int userHandle) {
3972        if (Binder.getCallingUid() == Process.SHELL_UID) {
3973            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3974                throw new SecurityException("Shell does not have permission to access user "
3975                        + userHandle);
3976            }
3977        }
3978    }
3979
3980    @Override
3981    public int getFrontActivityScreenCompatMode() {
3982        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3983        synchronized (this) {
3984            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3985        }
3986    }
3987
3988    @Override
3989    public void setFrontActivityScreenCompatMode(int mode) {
3990        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3991                "setFrontActivityScreenCompatMode");
3992        synchronized (this) {
3993            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3994        }
3995    }
3996
3997    @Override
3998    public int getPackageScreenCompatMode(String packageName) {
3999        enforceNotIsolatedCaller("getPackageScreenCompatMode");
4000        synchronized (this) {
4001            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4002        }
4003    }
4004
4005    @Override
4006    public void setPackageScreenCompatMode(String packageName, int mode) {
4007        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4008                "setPackageScreenCompatMode");
4009        synchronized (this) {
4010            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4011        }
4012    }
4013
4014    @Override
4015    public boolean getPackageAskScreenCompat(String packageName) {
4016        enforceNotIsolatedCaller("getPackageAskScreenCompat");
4017        synchronized (this) {
4018            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4019        }
4020    }
4021
4022    @Override
4023    public void setPackageAskScreenCompat(String packageName, boolean ask) {
4024        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4025                "setPackageAskScreenCompat");
4026        synchronized (this) {
4027            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4028        }
4029    }
4030
4031    private boolean hasUsageStatsPermission(String callingPackage) {
4032        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4033                Binder.getCallingUid(), callingPackage);
4034        if (mode == AppOpsManager.MODE_DEFAULT) {
4035            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4036                    == PackageManager.PERMISSION_GRANTED;
4037        }
4038        return mode == AppOpsManager.MODE_ALLOWED;
4039    }
4040
4041    @Override
4042    public int getPackageProcessState(String packageName, String callingPackage) {
4043        if (!hasUsageStatsPermission(callingPackage)) {
4044            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
4045                    "getPackageProcessState");
4046        }
4047
4048        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4049        synchronized (this) {
4050            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4051                final ProcessRecord proc = mLruProcesses.get(i);
4052                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
4053                        || procState > proc.setProcState) {
4054                    if (proc.pkgList.containsKey(packageName)) {
4055                        procState = proc.setProcState;
4056                        break;
4057                    }
4058                    if (proc.pkgDeps != null && proc.pkgDeps.contains(packageName)) {
4059                        procState = proc.setProcState;
4060                    }
4061                }
4062            }
4063        }
4064        return procState;
4065    }
4066
4067    @Override
4068    public boolean setProcessMemoryTrimLevel(String process, int userId, int level)
4069            throws RemoteException {
4070        synchronized (this) {
4071            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4072            if (app == null) {
4073                throw new IllegalArgumentException("Unknown process: " + process);
4074            }
4075            if (app.thread == null) {
4076                throw new IllegalArgumentException("Process has no app thread");
4077            }
4078            if (app.trimMemoryLevel >= level) {
4079                throw new IllegalArgumentException(
4080                        "Unable to set a higher trim level than current level");
4081            }
4082            if (!(level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4083                    app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4084                throw new IllegalArgumentException("Unable to set a background trim level "
4085                    + "on a foreground process");
4086            }
4087            app.thread.scheduleTrimMemory(level);
4088            app.trimMemoryLevel = level;
4089            return true;
4090        }
4091    }
4092
4093    private void dispatchProcessesChanged() {
4094        int N;
4095        synchronized (this) {
4096            N = mPendingProcessChanges.size();
4097            if (mActiveProcessChanges.length < N) {
4098                mActiveProcessChanges = new ProcessChangeItem[N];
4099            }
4100            mPendingProcessChanges.toArray(mActiveProcessChanges);
4101            mPendingProcessChanges.clear();
4102            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4103                    "*** Delivering " + N + " process changes");
4104        }
4105
4106        int i = mProcessObservers.beginBroadcast();
4107        while (i > 0) {
4108            i--;
4109            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4110            if (observer != null) {
4111                try {
4112                    for (int j=0; j<N; j++) {
4113                        ProcessChangeItem item = mActiveProcessChanges[j];
4114                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4115                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4116                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4117                                    + item.uid + ": " + item.foregroundActivities);
4118                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4119                                    item.foregroundActivities);
4120                        }
4121                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4122                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4123                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4124                                    + ": " + item.processState);
4125                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4126                        }
4127                    }
4128                } catch (RemoteException e) {
4129                }
4130            }
4131        }
4132        mProcessObservers.finishBroadcast();
4133
4134        synchronized (this) {
4135            for (int j=0; j<N; j++) {
4136                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4137            }
4138        }
4139    }
4140
4141    private void dispatchProcessDied(int pid, int uid) {
4142        int i = mProcessObservers.beginBroadcast();
4143        while (i > 0) {
4144            i--;
4145            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4146            if (observer != null) {
4147                try {
4148                    observer.onProcessDied(pid, uid);
4149                } catch (RemoteException e) {
4150                }
4151            }
4152        }
4153        mProcessObservers.finishBroadcast();
4154    }
4155
4156    private void dispatchUidsChanged() {
4157        int N;
4158        synchronized (this) {
4159            N = mPendingUidChanges.size();
4160            if (mActiveUidChanges.length < N) {
4161                mActiveUidChanges = new UidRecord.ChangeItem[N];
4162            }
4163            for (int i=0; i<N; i++) {
4164                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4165                mActiveUidChanges[i] = change;
4166                if (change.uidRecord != null) {
4167                    change.uidRecord.pendingChange = null;
4168                    change.uidRecord = null;
4169                }
4170            }
4171            mPendingUidChanges.clear();
4172            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4173                    "*** Delivering " + N + " uid changes");
4174        }
4175
4176        int i = mUidObservers.beginBroadcast();
4177        while (i > 0) {
4178            i--;
4179            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4180            final UidObserverRegistration reg = (UidObserverRegistration)
4181                    mUidObservers.getBroadcastCookie(i);
4182            if (observer != null) {
4183                try {
4184                    for (int j=0; j<N; j++) {
4185                        UidRecord.ChangeItem item = mActiveUidChanges[j];
4186                        final int change = item.change;
4187                        UidRecord validateUid = null;
4188                        if (VALIDATE_UID_STATES && i == 0) {
4189                            validateUid = mValidateUids.get(item.uid);
4190                            if (validateUid == null && change != UidRecord.CHANGE_GONE
4191                                    && change != UidRecord.CHANGE_GONE_IDLE) {
4192                                validateUid = new UidRecord(item.uid);
4193                                mValidateUids.put(item.uid, validateUid);
4194                            }
4195                        }
4196                        if (change == UidRecord.CHANGE_IDLE
4197                                || change == UidRecord.CHANGE_GONE_IDLE) {
4198                            if ((reg.which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4199                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4200                                        "UID idle uid=" + item.uid);
4201                                observer.onUidIdle(item.uid, item.ephemeral);
4202                            }
4203                            if (VALIDATE_UID_STATES && i == 0) {
4204                                if (validateUid != null) {
4205                                    validateUid.idle = true;
4206                                }
4207                            }
4208                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4209                            if ((reg.which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4210                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4211                                        "UID active uid=" + item.uid);
4212                                observer.onUidActive(item.uid);
4213                            }
4214                            if (VALIDATE_UID_STATES && i == 0) {
4215                                validateUid.idle = false;
4216                            }
4217                        }
4218                        if (change == UidRecord.CHANGE_GONE
4219                                || change == UidRecord.CHANGE_GONE_IDLE) {
4220                            if ((reg.which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4221                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4222                                        "UID gone uid=" + item.uid);
4223                                observer.onUidGone(item.uid, item.ephemeral);
4224                            }
4225                            if (reg.lastProcStates != null) {
4226                                reg.lastProcStates.delete(item.uid);
4227                            }
4228                            if (VALIDATE_UID_STATES && i == 0) {
4229                                if (validateUid != null) {
4230                                    mValidateUids.remove(item.uid);
4231                                }
4232                            }
4233                        } else {
4234                            if ((reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4235                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4236                                        "UID CHANGED uid=" + item.uid
4237                                                + ": " + item.processState);
4238                                boolean doReport = true;
4239                                if (reg.cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
4240                                    final int lastState = reg.lastProcStates.get(item.uid,
4241                                            ActivityManager.PROCESS_STATE_UNKNOWN);
4242                                    if (lastState != ActivityManager.PROCESS_STATE_UNKNOWN) {
4243                                        final boolean lastAboveCut = lastState <= reg.cutpoint;
4244                                        final boolean newAboveCut = item.processState <= reg.cutpoint;
4245                                        doReport = lastAboveCut != newAboveCut;
4246                                    } else {
4247                                        doReport = item.processState
4248                                                != ActivityManager.PROCESS_STATE_NONEXISTENT;
4249                                    }
4250                                }
4251                                if (doReport) {
4252                                    if (reg.lastProcStates != null) {
4253                                        reg.lastProcStates.put(item.uid, item.processState);
4254                                    }
4255                                    observer.onUidStateChanged(item.uid, item.processState);
4256                                }
4257                            }
4258                            if (VALIDATE_UID_STATES && i == 0) {
4259                                validateUid.curProcState = validateUid.setProcState
4260                                        = item.processState;
4261                            }
4262                        }
4263                    }
4264                } catch (RemoteException e) {
4265                }
4266            }
4267        }
4268        mUidObservers.finishBroadcast();
4269
4270        synchronized (this) {
4271            for (int j=0; j<N; j++) {
4272                mAvailUidChanges.add(mActiveUidChanges[j]);
4273            }
4274        }
4275    }
4276
4277    @Override
4278    public final int startActivity(IApplicationThread caller, String callingPackage,
4279            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4280            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4281        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4282                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4283                UserHandle.getCallingUserId());
4284    }
4285
4286    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4287        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4288        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4289                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4290                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4291
4292        // TODO: Switch to user app stacks here.
4293        String mimeType = intent.getType();
4294        final Uri data = intent.getData();
4295        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4296            mimeType = getProviderMimeType(data, userId);
4297        }
4298        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4299
4300        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4301        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4302                null, 0, 0, null, null, null, null, false, userId, container, null);
4303    }
4304
4305    @Override
4306    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4307            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4308            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4309        enforceNotIsolatedCaller("startActivity");
4310        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4311                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4312        // TODO: Switch to user app stacks here.
4313        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4314                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4315                profilerInfo, null, null, bOptions, false, userId, null, null);
4316    }
4317
4318    @Override
4319    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4320            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4321            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4322            int userId) {
4323
4324        // This is very dangerous -- it allows you to perform a start activity (including
4325        // permission grants) as any app that may launch one of your own activities.  So
4326        // we will only allow this to be done from activities that are part of the core framework,
4327        // and then only when they are running as the system.
4328        final ActivityRecord sourceRecord;
4329        final int targetUid;
4330        final String targetPackage;
4331        synchronized (this) {
4332            if (resultTo == null) {
4333                throw new SecurityException("Must be called from an activity");
4334            }
4335            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4336            if (sourceRecord == null) {
4337                throw new SecurityException("Called with bad activity token: " + resultTo);
4338            }
4339            if (!sourceRecord.info.packageName.equals("android")) {
4340                throw new SecurityException(
4341                        "Must be called from an activity that is declared in the android package");
4342            }
4343            if (sourceRecord.app == null) {
4344                throw new SecurityException("Called without a process attached to activity");
4345            }
4346            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4347                // This is still okay, as long as this activity is running under the
4348                // uid of the original calling activity.
4349                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4350                    throw new SecurityException(
4351                            "Calling activity in uid " + sourceRecord.app.uid
4352                                    + " must be system uid or original calling uid "
4353                                    + sourceRecord.launchedFromUid);
4354                }
4355            }
4356            if (ignoreTargetSecurity) {
4357                if (intent.getComponent() == null) {
4358                    throw new SecurityException(
4359                            "Component must be specified with ignoreTargetSecurity");
4360                }
4361                if (intent.getSelector() != null) {
4362                    throw new SecurityException(
4363                            "Selector not allowed with ignoreTargetSecurity");
4364                }
4365            }
4366            targetUid = sourceRecord.launchedFromUid;
4367            targetPackage = sourceRecord.launchedFromPackage;
4368        }
4369
4370        if (userId == UserHandle.USER_NULL) {
4371            userId = UserHandle.getUserId(sourceRecord.app.uid);
4372        }
4373
4374        // TODO: Switch to user app stacks here.
4375        try {
4376            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4377                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4378                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4379            return ret;
4380        } catch (SecurityException e) {
4381            // XXX need to figure out how to propagate to original app.
4382            // A SecurityException here is generally actually a fault of the original
4383            // calling activity (such as a fairly granting permissions), so propagate it
4384            // back to them.
4385            /*
4386            StringBuilder msg = new StringBuilder();
4387            msg.append("While launching");
4388            msg.append(intent.toString());
4389            msg.append(": ");
4390            msg.append(e.getMessage());
4391            */
4392            throw e;
4393        }
4394    }
4395
4396    @Override
4397    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4398            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4399            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4400        enforceNotIsolatedCaller("startActivityAndWait");
4401        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4402                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4403        WaitResult res = new WaitResult();
4404        // TODO: Switch to user app stacks here.
4405        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4406                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4407                bOptions, false, userId, null, null);
4408        return res;
4409    }
4410
4411    @Override
4412    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4413            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4414            int startFlags, Configuration config, Bundle bOptions, int userId) {
4415        enforceNotIsolatedCaller("startActivityWithConfig");
4416        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4417                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4418        // TODO: Switch to user app stacks here.
4419        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4420                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4421                null, null, config, bOptions, false, userId, null, null);
4422        return ret;
4423    }
4424
4425    @Override
4426    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4427            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4428            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4429            throws TransactionTooLargeException {
4430        enforceNotIsolatedCaller("startActivityIntentSender");
4431        // Refuse possible leaked file descriptors
4432        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4433            throw new IllegalArgumentException("File descriptors passed in Intent");
4434        }
4435
4436        IIntentSender sender = intent.getTarget();
4437        if (!(sender instanceof PendingIntentRecord)) {
4438            throw new IllegalArgumentException("Bad PendingIntent object");
4439        }
4440
4441        PendingIntentRecord pir = (PendingIntentRecord)sender;
4442
4443        synchronized (this) {
4444            // If this is coming from the currently resumed activity, it is
4445            // effectively saying that app switches are allowed at this point.
4446            final ActivityStack stack = getFocusedStack();
4447            if (stack.mResumedActivity != null &&
4448                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4449                mAppSwitchesAllowedTime = 0;
4450            }
4451        }
4452        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4453                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4454        return ret;
4455    }
4456
4457    @Override
4458    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4459            Intent intent, String resolvedType, IVoiceInteractionSession session,
4460            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4461            Bundle bOptions, int userId) {
4462        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4463                != PackageManager.PERMISSION_GRANTED) {
4464            String msg = "Permission Denial: startVoiceActivity() from pid="
4465                    + Binder.getCallingPid()
4466                    + ", uid=" + Binder.getCallingUid()
4467                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4468            Slog.w(TAG, msg);
4469            throw new SecurityException(msg);
4470        }
4471        if (session == null || interactor == null) {
4472            throw new NullPointerException("null session or interactor");
4473        }
4474        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4475                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4476        // TODO: Switch to user app stacks here.
4477        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4478                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4479                null, bOptions, false, userId, null, null);
4480    }
4481
4482    @Override
4483    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4484            throws RemoteException {
4485        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4486        synchronized (this) {
4487            ActivityRecord activity = getFocusedStack().topActivity();
4488            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4489                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4490            }
4491            if (mRunningVoice != null || activity.task.voiceSession != null
4492                    || activity.voiceSession != null) {
4493                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4494                return;
4495            }
4496            if (activity.pendingVoiceInteractionStart) {
4497                Slog.w(TAG, "Pending start of voice interaction already.");
4498                return;
4499            }
4500            activity.pendingVoiceInteractionStart = true;
4501        }
4502        LocalServices.getService(VoiceInteractionManagerInternal.class)
4503                .startLocalVoiceInteraction(callingActivity, options);
4504    }
4505
4506    @Override
4507    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4508        LocalServices.getService(VoiceInteractionManagerInternal.class)
4509                .stopLocalVoiceInteraction(callingActivity);
4510    }
4511
4512    @Override
4513    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4514        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4515                .supportsLocalVoiceInteraction();
4516    }
4517
4518    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4519            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4520        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4521        if (activityToCallback == null) return;
4522        activityToCallback.setVoiceSessionLocked(voiceSession);
4523
4524        // Inform the activity
4525        try {
4526            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4527                    voiceInteractor);
4528            long token = Binder.clearCallingIdentity();
4529            try {
4530                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4531            } finally {
4532                Binder.restoreCallingIdentity(token);
4533            }
4534            // TODO: VI Should we cache the activity so that it's easier to find later
4535            // rather than scan through all the stacks and activities?
4536        } catch (RemoteException re) {
4537            activityToCallback.clearVoiceSessionLocked();
4538            // TODO: VI Should this terminate the voice session?
4539        }
4540    }
4541
4542    @Override
4543    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4544        synchronized (this) {
4545            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4546                if (keepAwake) {
4547                    mVoiceWakeLock.acquire();
4548                } else {
4549                    mVoiceWakeLock.release();
4550                }
4551            }
4552        }
4553    }
4554
4555    @Override
4556    public boolean startNextMatchingActivity(IBinder callingActivity,
4557            Intent intent, Bundle bOptions) {
4558        // Refuse possible leaked file descriptors
4559        if (intent != null && intent.hasFileDescriptors() == true) {
4560            throw new IllegalArgumentException("File descriptors passed in Intent");
4561        }
4562        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4563
4564        synchronized (this) {
4565            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4566            if (r == null) {
4567                ActivityOptions.abort(options);
4568                return false;
4569            }
4570            if (r.app == null || r.app.thread == null) {
4571                // The caller is not running...  d'oh!
4572                ActivityOptions.abort(options);
4573                return false;
4574            }
4575            intent = new Intent(intent);
4576            // The caller is not allowed to change the data.
4577            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4578            // And we are resetting to find the next component...
4579            intent.setComponent(null);
4580
4581            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4582
4583            ActivityInfo aInfo = null;
4584            try {
4585                List<ResolveInfo> resolves =
4586                    AppGlobals.getPackageManager().queryIntentActivities(
4587                            intent, r.resolvedType,
4588                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4589                            UserHandle.getCallingUserId()).getList();
4590
4591                // Look for the original activity in the list...
4592                final int N = resolves != null ? resolves.size() : 0;
4593                for (int i=0; i<N; i++) {
4594                    ResolveInfo rInfo = resolves.get(i);
4595                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4596                            && rInfo.activityInfo.name.equals(r.info.name)) {
4597                        // We found the current one...  the next matching is
4598                        // after it.
4599                        i++;
4600                        if (i<N) {
4601                            aInfo = resolves.get(i).activityInfo;
4602                        }
4603                        if (debug) {
4604                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4605                                    + "/" + r.info.name);
4606                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4607                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4608                        }
4609                        break;
4610                    }
4611                }
4612            } catch (RemoteException e) {
4613            }
4614
4615            if (aInfo == null) {
4616                // Nobody who is next!
4617                ActivityOptions.abort(options);
4618                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4619                return false;
4620            }
4621
4622            intent.setComponent(new ComponentName(
4623                    aInfo.applicationInfo.packageName, aInfo.name));
4624            intent.setFlags(intent.getFlags()&~(
4625                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4626                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4627                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4628                    Intent.FLAG_ACTIVITY_NEW_TASK));
4629
4630            // Okay now we need to start the new activity, replacing the
4631            // currently running activity.  This is a little tricky because
4632            // we want to start the new one as if the current one is finished,
4633            // but not finish the current one first so that there is no flicker.
4634            // And thus...
4635            final boolean wasFinishing = r.finishing;
4636            r.finishing = true;
4637
4638            // Propagate reply information over to the new activity.
4639            final ActivityRecord resultTo = r.resultTo;
4640            final String resultWho = r.resultWho;
4641            final int requestCode = r.requestCode;
4642            r.resultTo = null;
4643            if (resultTo != null) {
4644                resultTo.removeResultsLocked(r, resultWho, requestCode);
4645            }
4646
4647            final long origId = Binder.clearCallingIdentity();
4648            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4649                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4650                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4651                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4652                    false, false, null, null, null);
4653            Binder.restoreCallingIdentity(origId);
4654
4655            r.finishing = wasFinishing;
4656            if (res != ActivityManager.START_SUCCESS) {
4657                return false;
4658            }
4659            return true;
4660        }
4661    }
4662
4663    @Override
4664    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4665        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4666            String msg = "Permission Denial: startActivityFromRecents called without " +
4667                    START_TASKS_FROM_RECENTS;
4668            Slog.w(TAG, msg);
4669            throw new SecurityException(msg);
4670        }
4671        final long origId = Binder.clearCallingIdentity();
4672        try {
4673            synchronized (this) {
4674                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4675            }
4676        } finally {
4677            Binder.restoreCallingIdentity(origId);
4678        }
4679    }
4680
4681    final int startActivityInPackage(int uid, String callingPackage,
4682            Intent intent, String resolvedType, IBinder resultTo,
4683            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4684            IActivityContainer container, TaskRecord inTask) {
4685
4686        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4687                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4688
4689        // TODO: Switch to user app stacks here.
4690        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4691                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4692                null, null, null, bOptions, false, userId, container, inTask);
4693        return ret;
4694    }
4695
4696    @Override
4697    public final int startActivities(IApplicationThread caller, String callingPackage,
4698            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4699            int userId) {
4700        enforceNotIsolatedCaller("startActivities");
4701        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4702                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4703        // TODO: Switch to user app stacks here.
4704        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4705                resolvedTypes, resultTo, bOptions, userId);
4706        return ret;
4707    }
4708
4709    final int startActivitiesInPackage(int uid, String callingPackage,
4710            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4711            Bundle bOptions, int userId) {
4712
4713        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4714                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4715        // TODO: Switch to user app stacks here.
4716        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4717                resultTo, bOptions, userId);
4718        return ret;
4719    }
4720
4721    @Override
4722    public void reportActivityFullyDrawn(IBinder token) {
4723        synchronized (this) {
4724            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4725            if (r == null) {
4726                return;
4727            }
4728            r.reportFullyDrawnLocked();
4729        }
4730    }
4731
4732    @Override
4733    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4734        synchronized (this) {
4735            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4736            if (r == null) {
4737                return;
4738            }
4739            final long origId = Binder.clearCallingIdentity();
4740            try {
4741                r.setRequestedOrientation(requestedOrientation);
4742            } finally {
4743                Binder.restoreCallingIdentity(origId);
4744            }
4745        }
4746    }
4747
4748    @Override
4749    public int getRequestedOrientation(IBinder token) {
4750        synchronized (this) {
4751            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4752            if (r == null) {
4753                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4754            }
4755            return r.getRequestedOrientation();
4756        }
4757    }
4758
4759    @Override
4760    public final void requestActivityRelaunch(IBinder token) {
4761        synchronized(this) {
4762            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4763            if (r == null) {
4764                return;
4765            }
4766            final long origId = Binder.clearCallingIdentity();
4767            try {
4768                r.forceNewConfig = true;
4769                r.ensureActivityConfigurationLocked(0 /* globalChanges */,
4770                        false /* preserveWindow */);
4771            } finally {
4772                Binder.restoreCallingIdentity(origId);
4773            }
4774        }
4775    }
4776
4777    /**
4778     * This is the internal entry point for handling Activity.finish().
4779     *
4780     * @param token The Binder token referencing the Activity we want to finish.
4781     * @param resultCode Result code, if any, from this Activity.
4782     * @param resultData Result data (Intent), if any, from this Activity.
4783     * @param finishTask Whether to finish the task associated with this Activity.
4784     *
4785     * @return Returns true if the activity successfully finished, or false if it is still running.
4786     */
4787    @Override
4788    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4789            int finishTask) {
4790        // Refuse possible leaked file descriptors
4791        if (resultData != null && resultData.hasFileDescriptors() == true) {
4792            throw new IllegalArgumentException("File descriptors passed in Intent");
4793        }
4794
4795        synchronized(this) {
4796            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4797            if (r == null) {
4798                return true;
4799            }
4800            // Keep track of the root activity of the task before we finish it
4801            TaskRecord tr = r.task;
4802            ActivityRecord rootR = tr.getRootActivity();
4803            if (rootR == null) {
4804                Slog.w(TAG, "Finishing task with all activities already finished");
4805            }
4806            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4807            // finish.
4808            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4809                    mStackSupervisor.isLastLockedTask(tr)) {
4810                Slog.i(TAG, "Not finishing task in lock task mode");
4811                mStackSupervisor.showLockTaskToast();
4812                return false;
4813            }
4814            if (mController != null) {
4815                // Find the first activity that is not finishing.
4816                ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
4817                if (next != null) {
4818                    // ask watcher if this is allowed
4819                    boolean resumeOK = true;
4820                    try {
4821                        resumeOK = mController.activityResuming(next.packageName);
4822                    } catch (RemoteException e) {
4823                        mController = null;
4824                        Watchdog.getInstance().setActivityController(null);
4825                    }
4826
4827                    if (!resumeOK) {
4828                        Slog.i(TAG, "Not finishing activity because controller resumed");
4829                        return false;
4830                    }
4831                }
4832            }
4833            final long origId = Binder.clearCallingIdentity();
4834            try {
4835                boolean res;
4836                final boolean finishWithRootActivity =
4837                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4838                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4839                        || (finishWithRootActivity && r == rootR)) {
4840                    // If requested, remove the task that is associated to this activity only if it
4841                    // was the root activity in the task. The result code and data is ignored
4842                    // because we don't support returning them across task boundaries. Also, to
4843                    // keep backwards compatibility we remove the task from recents when finishing
4844                    // task with root activity.
4845                    res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4846                    if (!res) {
4847                        Slog.i(TAG, "Removing task failed to finish activity");
4848                    }
4849                } else {
4850                    res = tr.getStack().requestFinishActivityLocked(token, resultCode,
4851                            resultData, "app-request", true);
4852                    if (!res) {
4853                        Slog.i(TAG, "Failed to finish by app-request");
4854                    }
4855                }
4856                return res;
4857            } finally {
4858                Binder.restoreCallingIdentity(origId);
4859            }
4860        }
4861    }
4862
4863    @Override
4864    public final void finishHeavyWeightApp() {
4865        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4866                != PackageManager.PERMISSION_GRANTED) {
4867            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4868                    + Binder.getCallingPid()
4869                    + ", uid=" + Binder.getCallingUid()
4870                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4871            Slog.w(TAG, msg);
4872            throw new SecurityException(msg);
4873        }
4874
4875        synchronized(this) {
4876            if (mHeavyWeightProcess == null) {
4877                return;
4878            }
4879
4880            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4881            for (int i = 0; i < activities.size(); i++) {
4882                ActivityRecord r = activities.get(i);
4883                if (!r.finishing && r.isInStackLocked()) {
4884                    r.getStack().finishActivityLocked(r, Activity.RESULT_CANCELED,
4885                            null, "finish-heavy", true);
4886                }
4887            }
4888
4889            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4890                    mHeavyWeightProcess.userId, 0));
4891            mHeavyWeightProcess = null;
4892        }
4893    }
4894
4895    @Override
4896    public void crashApplication(int uid, int initialPid, String packageName,
4897            String message) {
4898        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4899                != PackageManager.PERMISSION_GRANTED) {
4900            String msg = "Permission Denial: crashApplication() from pid="
4901                    + Binder.getCallingPid()
4902                    + ", uid=" + Binder.getCallingUid()
4903                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4904            Slog.w(TAG, msg);
4905            throw new SecurityException(msg);
4906        }
4907
4908        synchronized(this) {
4909            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4910        }
4911    }
4912
4913    @Override
4914    public final void finishSubActivity(IBinder token, String resultWho,
4915            int requestCode) {
4916        synchronized(this) {
4917            final long origId = Binder.clearCallingIdentity();
4918            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4919            if (r != null) {
4920                r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
4921            }
4922            Binder.restoreCallingIdentity(origId);
4923        }
4924    }
4925
4926    @Override
4927    public boolean finishActivityAffinity(IBinder token) {
4928        synchronized(this) {
4929            final long origId = Binder.clearCallingIdentity();
4930            try {
4931                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4932                if (r == null) {
4933                    return false;
4934                }
4935
4936                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4937                // can finish.
4938                final TaskRecord task = r.task;
4939                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4940                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4941                    mStackSupervisor.showLockTaskToast();
4942                    return false;
4943                }
4944                return task.getStack().finishActivityAffinityLocked(r);
4945            } finally {
4946                Binder.restoreCallingIdentity(origId);
4947            }
4948        }
4949    }
4950
4951    @Override
4952    public void finishVoiceTask(IVoiceInteractionSession session) {
4953        synchronized (this) {
4954            final long origId = Binder.clearCallingIdentity();
4955            try {
4956                // TODO: VI Consider treating local voice interactions and voice tasks
4957                // differently here
4958                mStackSupervisor.finishVoiceTask(session);
4959            } finally {
4960                Binder.restoreCallingIdentity(origId);
4961            }
4962        }
4963
4964    }
4965
4966    @Override
4967    public boolean releaseActivityInstance(IBinder token) {
4968        synchronized(this) {
4969            final long origId = Binder.clearCallingIdentity();
4970            try {
4971                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4972                if (r == null) {
4973                    return false;
4974                }
4975                return r.getStack().safelyDestroyActivityLocked(r, "app-req");
4976            } finally {
4977                Binder.restoreCallingIdentity(origId);
4978            }
4979        }
4980    }
4981
4982    @Override
4983    public void releaseSomeActivities(IApplicationThread appInt) {
4984        synchronized(this) {
4985            final long origId = Binder.clearCallingIdentity();
4986            try {
4987                ProcessRecord app = getRecordForAppLocked(appInt);
4988                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4989            } finally {
4990                Binder.restoreCallingIdentity(origId);
4991            }
4992        }
4993    }
4994
4995    @Override
4996    public boolean willActivityBeVisible(IBinder token) {
4997        synchronized(this) {
4998            ActivityStack stack = ActivityRecord.getStackLocked(token);
4999            if (stack != null) {
5000                return stack.willActivityBeVisibleLocked(token);
5001            }
5002            return false;
5003        }
5004    }
5005
5006    @Override
5007    public void overridePendingTransition(IBinder token, String packageName,
5008            int enterAnim, int exitAnim) {
5009        synchronized(this) {
5010            ActivityRecord self = ActivityRecord.isInStackLocked(token);
5011            if (self == null) {
5012                return;
5013            }
5014
5015            final long origId = Binder.clearCallingIdentity();
5016
5017            if (self.state == ActivityState.RESUMED
5018                    || self.state == ActivityState.PAUSING) {
5019                mWindowManager.overridePendingAppTransition(packageName,
5020                        enterAnim, exitAnim, null);
5021            }
5022
5023            Binder.restoreCallingIdentity(origId);
5024        }
5025    }
5026
5027    /**
5028     * Main function for removing an existing process from the activity manager
5029     * as a result of that process going away.  Clears out all connections
5030     * to the process.
5031     */
5032    private final void handleAppDiedLocked(ProcessRecord app,
5033            boolean restarting, boolean allowRestart) {
5034        int pid = app.pid;
5035        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5036                false /*replacingPid*/);
5037        if (!kept && !restarting) {
5038            removeLruProcessLocked(app);
5039            if (pid > 0) {
5040                ProcessList.remove(pid);
5041            }
5042        }
5043
5044        if (mProfileProc == app) {
5045            clearProfilerLocked();
5046        }
5047
5048        // Remove this application's activities from active lists.
5049        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5050
5051        app.activities.clear();
5052
5053        if (app.instrumentationClass != null) {
5054            Slog.w(TAG, "Crash of app " + app.processName
5055                  + " running instrumentation " + app.instrumentationClass);
5056            Bundle info = new Bundle();
5057            info.putString("shortMsg", "Process crashed.");
5058            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5059        }
5060
5061        mWindowManager.deferSurfaceLayout();
5062        try {
5063            if (!restarting && hasVisibleActivities
5064                    && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5065                // If there was nothing to resume, and we are not already restarting this process, but
5066                // there is a visible activity that is hosted by the process...  then make sure all
5067                // visible activities are running, taking care of restarting this process.
5068                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5069            }
5070        } finally {
5071            mWindowManager.continueSurfaceLayout();
5072        }
5073    }
5074
5075    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5076        IBinder threadBinder = thread.asBinder();
5077        // Find the application record.
5078        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5079            ProcessRecord rec = mLruProcesses.get(i);
5080            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5081                return i;
5082            }
5083        }
5084        return -1;
5085    }
5086
5087    final ProcessRecord getRecordForAppLocked(
5088            IApplicationThread thread) {
5089        if (thread == null) {
5090            return null;
5091        }
5092
5093        int appIndex = getLRURecordIndexForAppLocked(thread);
5094        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
5095    }
5096
5097    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5098        // If there are no longer any background processes running,
5099        // and the app that died was not running instrumentation,
5100        // then tell everyone we are now low on memory.
5101        boolean haveBg = false;
5102        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5103            ProcessRecord rec = mLruProcesses.get(i);
5104            if (rec.thread != null
5105                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5106                haveBg = true;
5107                break;
5108            }
5109        }
5110
5111        if (!haveBg) {
5112            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5113            if (doReport) {
5114                long now = SystemClock.uptimeMillis();
5115                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5116                    doReport = false;
5117                } else {
5118                    mLastMemUsageReportTime = now;
5119                }
5120            }
5121            final ArrayList<ProcessMemInfo> memInfos
5122                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5123            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5124            long now = SystemClock.uptimeMillis();
5125            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5126                ProcessRecord rec = mLruProcesses.get(i);
5127                if (rec == dyingProc || rec.thread == null) {
5128                    continue;
5129                }
5130                if (doReport) {
5131                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5132                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5133                }
5134                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5135                    // The low memory report is overriding any current
5136                    // state for a GC request.  Make sure to do
5137                    // heavy/important/visible/foreground processes first.
5138                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5139                        rec.lastRequestedGc = 0;
5140                    } else {
5141                        rec.lastRequestedGc = rec.lastLowMemory;
5142                    }
5143                    rec.reportLowMemory = true;
5144                    rec.lastLowMemory = now;
5145                    mProcessesToGc.remove(rec);
5146                    addProcessToGcListLocked(rec);
5147                }
5148            }
5149            if (doReport) {
5150                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5151                mHandler.sendMessage(msg);
5152            }
5153            scheduleAppGcsLocked();
5154        }
5155    }
5156
5157    final void appDiedLocked(ProcessRecord app) {
5158       appDiedLocked(app, app.pid, app.thread, false);
5159    }
5160
5161    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5162            boolean fromBinderDied) {
5163        // First check if this ProcessRecord is actually active for the pid.
5164        synchronized (mPidsSelfLocked) {
5165            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5166            if (curProc != app) {
5167                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5168                return;
5169            }
5170        }
5171
5172        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5173        synchronized (stats) {
5174            stats.noteProcessDiedLocked(app.info.uid, pid);
5175        }
5176
5177        if (!app.killed) {
5178            if (!fromBinderDied) {
5179                Process.killProcessQuiet(pid);
5180            }
5181            killProcessGroup(app.uid, pid);
5182            app.killed = true;
5183        }
5184
5185        // Clean up already done if the process has been re-started.
5186        if (app.pid == pid && app.thread != null &&
5187                app.thread.asBinder() == thread.asBinder()) {
5188            boolean doLowMem = app.instrumentationClass == null;
5189            boolean doOomAdj = doLowMem;
5190            if (!app.killedByAm) {
5191                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5192                        + ") has died");
5193                mAllowLowerMemLevel = true;
5194            } else {
5195                // Note that we always want to do oom adj to update our state with the
5196                // new number of procs.
5197                mAllowLowerMemLevel = false;
5198                doLowMem = false;
5199            }
5200            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5201            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5202                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5203            handleAppDiedLocked(app, false, true);
5204
5205            if (doOomAdj) {
5206                updateOomAdjLocked();
5207            }
5208            if (doLowMem) {
5209                doLowMemReportIfNeededLocked(app);
5210            }
5211        } else if (app.pid != pid) {
5212            // A new process has already been started.
5213            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5214                    + ") has died and restarted (pid " + app.pid + ").");
5215            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5216        } else if (DEBUG_PROCESSES) {
5217            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5218                    + thread.asBinder());
5219        }
5220    }
5221
5222    /**
5223     * If a stack trace dump file is configured, dump process stack traces.
5224     * @param clearTraces causes the dump file to be erased prior to the new
5225     *    traces being written, if true; when false, the new traces will be
5226     *    appended to any existing file content.
5227     * @param firstPids of dalvik VM processes to dump stack traces for first
5228     * @param lastPids of dalvik VM processes to dump stack traces for last
5229     * @param nativeProcs optional list of native process names to dump stack crawls
5230     * @return file containing stack traces, or null if no dump file is configured
5231     */
5232    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5233            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5234        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5235        if (tracesPath == null || tracesPath.length() == 0) {
5236            return null;
5237        }
5238
5239        File tracesFile = new File(tracesPath);
5240        try {
5241            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5242            tracesFile.createNewFile();
5243            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5244        } catch (IOException e) {
5245            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5246            return null;
5247        }
5248
5249        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5250        return tracesFile;
5251    }
5252
5253    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5254            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5255        // Use a FileObserver to detect when traces finish writing.
5256        // The order of traces is considered important to maintain for legibility.
5257        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5258            @Override
5259            public synchronized void onEvent(int event, String path) { notify(); }
5260        };
5261
5262        try {
5263            observer.startWatching();
5264
5265            // First collect all of the stacks of the most important pids.
5266            if (firstPids != null) {
5267                try {
5268                    int num = firstPids.size();
5269                    for (int i = 0; i < num; i++) {
5270                        synchronized (observer) {
5271                            if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5272                                    + firstPids.get(i));
5273                            final long sime = SystemClock.elapsedRealtime();
5274                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5275                            observer.wait(1000);  // Wait for write-close, give up after 1 sec
5276                            if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5277                                    + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5278                        }
5279                    }
5280                } catch (InterruptedException e) {
5281                    Slog.wtf(TAG, e);
5282                }
5283            }
5284
5285            // Next collect the stacks of the native pids
5286            if (nativeProcs != null) {
5287                int[] pids = Process.getPidsForCommands(nativeProcs);
5288                if (pids != null) {
5289                    for (int pid : pids) {
5290                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5291                        final long sime = SystemClock.elapsedRealtime();
5292                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5293                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5294                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5295                    }
5296                }
5297            }
5298
5299            // Lastly, measure CPU usage.
5300            if (processCpuTracker != null) {
5301                processCpuTracker.init();
5302                System.gc();
5303                processCpuTracker.update();
5304                try {
5305                    synchronized (processCpuTracker) {
5306                        processCpuTracker.wait(500); // measure over 1/2 second.
5307                    }
5308                } catch (InterruptedException e) {
5309                }
5310                processCpuTracker.update();
5311
5312                // We'll take the stack crawls of just the top apps using CPU.
5313                final int N = processCpuTracker.countWorkingStats();
5314                int numProcs = 0;
5315                for (int i=0; i<N && numProcs<5; i++) {
5316                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5317                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5318                        numProcs++;
5319                        try {
5320                            synchronized (observer) {
5321                                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5322                                        + stats.pid);
5323                                final long stime = SystemClock.elapsedRealtime();
5324                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5325                                observer.wait(1000);  // Wait for write-close, give up after 1 sec
5326                                if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5327                                        + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5328                            }
5329                        } catch (InterruptedException e) {
5330                            Slog.wtf(TAG, e);
5331                        }
5332                    } else if (DEBUG_ANR) {
5333                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5334                                + stats.pid);
5335                    }
5336                }
5337            }
5338        } finally {
5339            observer.stopWatching();
5340        }
5341    }
5342
5343    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5344        if (true || IS_USER_BUILD) {
5345            return;
5346        }
5347        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5348        if (tracesPath == null || tracesPath.length() == 0) {
5349            return;
5350        }
5351
5352        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5353        StrictMode.allowThreadDiskWrites();
5354        try {
5355            final File tracesFile = new File(tracesPath);
5356            final File tracesDir = tracesFile.getParentFile();
5357            final File tracesTmp = new File(tracesDir, "__tmp__");
5358            try {
5359                if (tracesFile.exists()) {
5360                    tracesTmp.delete();
5361                    tracesFile.renameTo(tracesTmp);
5362                }
5363                StringBuilder sb = new StringBuilder();
5364                Time tobj = new Time();
5365                tobj.set(System.currentTimeMillis());
5366                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5367                sb.append(": ");
5368                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5369                sb.append(" since ");
5370                sb.append(msg);
5371                FileOutputStream fos = new FileOutputStream(tracesFile);
5372                fos.write(sb.toString().getBytes());
5373                if (app == null) {
5374                    fos.write("\n*** No application process!".getBytes());
5375                }
5376                fos.close();
5377                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5378            } catch (IOException e) {
5379                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5380                return;
5381            }
5382
5383            if (app != null) {
5384                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5385                firstPids.add(app.pid);
5386                dumpStackTraces(tracesPath, firstPids, null, null, null);
5387            }
5388
5389            File lastTracesFile = null;
5390            File curTracesFile = null;
5391            for (int i=9; i>=0; i--) {
5392                String name = String.format(Locale.US, "slow%02d.txt", i);
5393                curTracesFile = new File(tracesDir, name);
5394                if (curTracesFile.exists()) {
5395                    if (lastTracesFile != null) {
5396                        curTracesFile.renameTo(lastTracesFile);
5397                    } else {
5398                        curTracesFile.delete();
5399                    }
5400                }
5401                lastTracesFile = curTracesFile;
5402            }
5403            tracesFile.renameTo(curTracesFile);
5404            if (tracesTmp.exists()) {
5405                tracesTmp.renameTo(tracesFile);
5406            }
5407        } finally {
5408            StrictMode.setThreadPolicy(oldPolicy);
5409        }
5410    }
5411
5412    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5413        if (!mLaunchWarningShown) {
5414            mLaunchWarningShown = true;
5415            mUiHandler.post(new Runnable() {
5416                @Override
5417                public void run() {
5418                    synchronized (ActivityManagerService.this) {
5419                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5420                        d.show();
5421                        mUiHandler.postDelayed(new Runnable() {
5422                            @Override
5423                            public void run() {
5424                                synchronized (ActivityManagerService.this) {
5425                                    d.dismiss();
5426                                    mLaunchWarningShown = false;
5427                                }
5428                            }
5429                        }, 4000);
5430                    }
5431                }
5432            });
5433        }
5434    }
5435
5436    @Override
5437    public boolean clearApplicationUserData(final String packageName,
5438            final IPackageDataObserver observer, int userId) {
5439        enforceNotIsolatedCaller("clearApplicationUserData");
5440        int uid = Binder.getCallingUid();
5441        int pid = Binder.getCallingPid();
5442        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5443                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5444
5445
5446        long callingId = Binder.clearCallingIdentity();
5447        try {
5448            IPackageManager pm = AppGlobals.getPackageManager();
5449            int pkgUid = -1;
5450            synchronized(this) {
5451                if (getPackageManagerInternalLocked().isPackageDataProtected(
5452                        userId, packageName)) {
5453                    throw new SecurityException(
5454                            "Cannot clear data for a protected package: " + packageName);
5455                }
5456
5457                try {
5458                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5459                } catch (RemoteException e) {
5460                }
5461                if (pkgUid == -1) {
5462                    Slog.w(TAG, "Invalid packageName: " + packageName);
5463                    if (observer != null) {
5464                        try {
5465                            observer.onRemoveCompleted(packageName, false);
5466                        } catch (RemoteException e) {
5467                            Slog.i(TAG, "Observer no longer exists.");
5468                        }
5469                    }
5470                    return false;
5471                }
5472                if (uid == pkgUid || checkComponentPermission(
5473                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5474                        pid, uid, -1, true)
5475                        == PackageManager.PERMISSION_GRANTED) {
5476                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5477                } else {
5478                    throw new SecurityException("PID " + pid + " does not have permission "
5479                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5480                                    + " of package " + packageName);
5481                }
5482
5483                // Remove all tasks match the cleared application package and user
5484                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5485                    final TaskRecord tr = mRecentTasks.get(i);
5486                    final String taskPackageName =
5487                            tr.getBaseIntent().getComponent().getPackageName();
5488                    if (tr.userId != userId) continue;
5489                    if (!taskPackageName.equals(packageName)) continue;
5490                    mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5491                }
5492            }
5493
5494            final int pkgUidF = pkgUid;
5495            final int userIdF = userId;
5496            final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5497                @Override
5498                public void onRemoveCompleted(String packageName, boolean succeeded)
5499                        throws RemoteException {
5500                    synchronized (ActivityManagerService.this) {
5501                        finishForceStopPackageLocked(packageName, pkgUidF);
5502                    }
5503
5504                    final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5505                            Uri.fromParts("package", packageName, null));
5506                    intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5507                    intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5508                    broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5509                            null, null, 0, null, null, null, null, false, false, userIdF);
5510
5511                    if (observer != null) {
5512                        observer.onRemoveCompleted(packageName, succeeded);
5513                    }
5514                }
5515            };
5516
5517            try {
5518                // Clear application user data
5519                pm.clearApplicationUserData(packageName, localObserver, userId);
5520
5521                synchronized(this) {
5522                    // Remove all permissions granted from/to this package
5523                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5524                }
5525
5526                // Remove all zen rules created by this package; revoke it's zen access.
5527                INotificationManager inm = NotificationManager.getService();
5528                inm.removeAutomaticZenRules(packageName);
5529                inm.setNotificationPolicyAccessGranted(packageName, false);
5530
5531            } catch (RemoteException e) {
5532            }
5533        } finally {
5534            Binder.restoreCallingIdentity(callingId);
5535        }
5536        return true;
5537    }
5538
5539    @Override
5540    public void killBackgroundProcesses(final String packageName, int userId) {
5541        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5542                != PackageManager.PERMISSION_GRANTED &&
5543                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5544                        != PackageManager.PERMISSION_GRANTED) {
5545            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5546                    + Binder.getCallingPid()
5547                    + ", uid=" + Binder.getCallingUid()
5548                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5549            Slog.w(TAG, msg);
5550            throw new SecurityException(msg);
5551        }
5552
5553        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5554                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5555        long callingId = Binder.clearCallingIdentity();
5556        try {
5557            IPackageManager pm = AppGlobals.getPackageManager();
5558            synchronized(this) {
5559                int appId = -1;
5560                try {
5561                    appId = UserHandle.getAppId(
5562                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5563                } catch (RemoteException e) {
5564                }
5565                if (appId == -1) {
5566                    Slog.w(TAG, "Invalid packageName: " + packageName);
5567                    return;
5568                }
5569                killPackageProcessesLocked(packageName, appId, userId,
5570                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5571            }
5572        } finally {
5573            Binder.restoreCallingIdentity(callingId);
5574        }
5575    }
5576
5577    @Override
5578    public void killAllBackgroundProcesses() {
5579        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5580                != PackageManager.PERMISSION_GRANTED) {
5581            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5582                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5583                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5584            Slog.w(TAG, msg);
5585            throw new SecurityException(msg);
5586        }
5587
5588        final long callingId = Binder.clearCallingIdentity();
5589        try {
5590            synchronized (this) {
5591                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5592                final int NP = mProcessNames.getMap().size();
5593                for (int ip = 0; ip < NP; ip++) {
5594                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5595                    final int NA = apps.size();
5596                    for (int ia = 0; ia < NA; ia++) {
5597                        final ProcessRecord app = apps.valueAt(ia);
5598                        if (app.persistent) {
5599                            // We don't kill persistent processes.
5600                            continue;
5601                        }
5602                        if (app.removed) {
5603                            procs.add(app);
5604                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5605                            app.removed = true;
5606                            procs.add(app);
5607                        }
5608                    }
5609                }
5610
5611                final int N = procs.size();
5612                for (int i = 0; i < N; i++) {
5613                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5614                }
5615
5616                mAllowLowerMemLevel = true;
5617
5618                updateOomAdjLocked();
5619                doLowMemReportIfNeededLocked(null);
5620            }
5621        } finally {
5622            Binder.restoreCallingIdentity(callingId);
5623        }
5624    }
5625
5626    /**
5627     * Kills all background processes, except those matching any of the
5628     * specified properties.
5629     *
5630     * @param minTargetSdk the target SDK version at or above which to preserve
5631     *                     processes, or {@code -1} to ignore the target SDK
5632     * @param maxProcState the process state at or below which to preserve
5633     *                     processes, or {@code -1} to ignore the process state
5634     */
5635    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5636        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5637                != PackageManager.PERMISSION_GRANTED) {
5638            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5639                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5640                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5641            Slog.w(TAG, msg);
5642            throw new SecurityException(msg);
5643        }
5644
5645        final long callingId = Binder.clearCallingIdentity();
5646        try {
5647            synchronized (this) {
5648                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5649                final int NP = mProcessNames.getMap().size();
5650                for (int ip = 0; ip < NP; ip++) {
5651                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5652                    final int NA = apps.size();
5653                    for (int ia = 0; ia < NA; ia++) {
5654                        final ProcessRecord app = apps.valueAt(ia);
5655                        if (app.removed) {
5656                            procs.add(app);
5657                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5658                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5659                            app.removed = true;
5660                            procs.add(app);
5661                        }
5662                    }
5663                }
5664
5665                final int N = procs.size();
5666                for (int i = 0; i < N; i++) {
5667                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5668                }
5669            }
5670        } finally {
5671            Binder.restoreCallingIdentity(callingId);
5672        }
5673    }
5674
5675    @Override
5676    public void forceStopPackage(final String packageName, int userId) {
5677        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5678                != PackageManager.PERMISSION_GRANTED) {
5679            String msg = "Permission Denial: forceStopPackage() from pid="
5680                    + Binder.getCallingPid()
5681                    + ", uid=" + Binder.getCallingUid()
5682                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5683            Slog.w(TAG, msg);
5684            throw new SecurityException(msg);
5685        }
5686        final int callingPid = Binder.getCallingPid();
5687        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5688                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5689        long callingId = Binder.clearCallingIdentity();
5690        try {
5691            IPackageManager pm = AppGlobals.getPackageManager();
5692            synchronized(this) {
5693                int[] users = userId == UserHandle.USER_ALL
5694                        ? mUserController.getUsers() : new int[] { userId };
5695                for (int user : users) {
5696                    int pkgUid = -1;
5697                    try {
5698                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5699                                user);
5700                    } catch (RemoteException e) {
5701                    }
5702                    if (pkgUid == -1) {
5703                        Slog.w(TAG, "Invalid packageName: " + packageName);
5704                        continue;
5705                    }
5706                    try {
5707                        pm.setPackageStoppedState(packageName, true, user);
5708                    } catch (RemoteException e) {
5709                    } catch (IllegalArgumentException e) {
5710                        Slog.w(TAG, "Failed trying to unstop package "
5711                                + packageName + ": " + e);
5712                    }
5713                    if (mUserController.isUserRunningLocked(user, 0)) {
5714                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5715                        finishForceStopPackageLocked(packageName, pkgUid);
5716                    }
5717                }
5718            }
5719        } finally {
5720            Binder.restoreCallingIdentity(callingId);
5721        }
5722    }
5723
5724    @Override
5725    public void addPackageDependency(String packageName) {
5726        synchronized (this) {
5727            int callingPid = Binder.getCallingPid();
5728            if (callingPid == Process.myPid()) {
5729                //  Yeah, um, no.
5730                return;
5731            }
5732            ProcessRecord proc;
5733            synchronized (mPidsSelfLocked) {
5734                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5735            }
5736            if (proc != null) {
5737                if (proc.pkgDeps == null) {
5738                    proc.pkgDeps = new ArraySet<String>(1);
5739                }
5740                proc.pkgDeps.add(packageName);
5741            }
5742        }
5743    }
5744
5745    /*
5746     * The pkg name and app id have to be specified.
5747     */
5748    @Override
5749    public void killApplication(String pkg, int appId, int userId, String reason) {
5750        if (pkg == null) {
5751            return;
5752        }
5753        // Make sure the uid is valid.
5754        if (appId < 0) {
5755            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5756            return;
5757        }
5758        int callerUid = Binder.getCallingUid();
5759        // Only the system server can kill an application
5760        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5761            // Post an aysnc message to kill the application
5762            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5763            msg.arg1 = appId;
5764            msg.arg2 = userId;
5765            Bundle bundle = new Bundle();
5766            bundle.putString("pkg", pkg);
5767            bundle.putString("reason", reason);
5768            msg.obj = bundle;
5769            mHandler.sendMessage(msg);
5770        } else {
5771            throw new SecurityException(callerUid + " cannot kill pkg: " +
5772                    pkg);
5773        }
5774    }
5775
5776    @Override
5777    public void closeSystemDialogs(String reason) {
5778        enforceNotIsolatedCaller("closeSystemDialogs");
5779
5780        final int pid = Binder.getCallingPid();
5781        final int uid = Binder.getCallingUid();
5782        final long origId = Binder.clearCallingIdentity();
5783        try {
5784            synchronized (this) {
5785                // Only allow this from foreground processes, so that background
5786                // applications can't abuse it to prevent system UI from being shown.
5787                if (uid >= Process.FIRST_APPLICATION_UID) {
5788                    ProcessRecord proc;
5789                    synchronized (mPidsSelfLocked) {
5790                        proc = mPidsSelfLocked.get(pid);
5791                    }
5792                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5793                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5794                                + " from background process " + proc);
5795                        return;
5796                    }
5797                }
5798                closeSystemDialogsLocked(reason);
5799            }
5800        } finally {
5801            Binder.restoreCallingIdentity(origId);
5802        }
5803    }
5804
5805    void closeSystemDialogsLocked(String reason) {
5806        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5807        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5808                | Intent.FLAG_RECEIVER_FOREGROUND);
5809        if (reason != null) {
5810            intent.putExtra("reason", reason);
5811        }
5812        mWindowManager.closeSystemDialogs(reason);
5813
5814        mStackSupervisor.closeSystemDialogsLocked();
5815
5816        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5817                AppOpsManager.OP_NONE, null, false, false,
5818                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5819    }
5820
5821    @Override
5822    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5823        enforceNotIsolatedCaller("getProcessMemoryInfo");
5824        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5825        for (int i=pids.length-1; i>=0; i--) {
5826            ProcessRecord proc;
5827            int oomAdj;
5828            synchronized (this) {
5829                synchronized (mPidsSelfLocked) {
5830                    proc = mPidsSelfLocked.get(pids[i]);
5831                    oomAdj = proc != null ? proc.setAdj : 0;
5832                }
5833            }
5834            infos[i] = new Debug.MemoryInfo();
5835            Debug.getMemoryInfo(pids[i], infos[i]);
5836            if (proc != null) {
5837                synchronized (this) {
5838                    if (proc.thread != null && proc.setAdj == oomAdj) {
5839                        // Record this for posterity if the process has been stable.
5840                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5841                                infos[i].getTotalUss(), false, proc.pkgList);
5842                    }
5843                }
5844            }
5845        }
5846        return infos;
5847    }
5848
5849    @Override
5850    public long[] getProcessPss(int[] pids) {
5851        enforceNotIsolatedCaller("getProcessPss");
5852        long[] pss = new long[pids.length];
5853        for (int i=pids.length-1; i>=0; i--) {
5854            ProcessRecord proc;
5855            int oomAdj;
5856            synchronized (this) {
5857                synchronized (mPidsSelfLocked) {
5858                    proc = mPidsSelfLocked.get(pids[i]);
5859                    oomAdj = proc != null ? proc.setAdj : 0;
5860                }
5861            }
5862            long[] tmpUss = new long[1];
5863            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5864            if (proc != null) {
5865                synchronized (this) {
5866                    if (proc.thread != null && proc.setAdj == oomAdj) {
5867                        // Record this for posterity if the process has been stable.
5868                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5869                    }
5870                }
5871            }
5872        }
5873        return pss;
5874    }
5875
5876    @Override
5877    public void killApplicationProcess(String processName, int uid) {
5878        if (processName == null) {
5879            return;
5880        }
5881
5882        int callerUid = Binder.getCallingUid();
5883        // Only the system server can kill an application
5884        if (callerUid == Process.SYSTEM_UID) {
5885            synchronized (this) {
5886                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5887                if (app != null && app.thread != null) {
5888                    try {
5889                        app.thread.scheduleSuicide();
5890                    } catch (RemoteException e) {
5891                        // If the other end already died, then our work here is done.
5892                    }
5893                } else {
5894                    Slog.w(TAG, "Process/uid not found attempting kill of "
5895                            + processName + " / " + uid);
5896                }
5897            }
5898        } else {
5899            throw new SecurityException(callerUid + " cannot kill app process: " +
5900                    processName);
5901        }
5902    }
5903
5904    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5905        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5906                false, true, false, false, UserHandle.getUserId(uid), reason);
5907    }
5908
5909    private void finishForceStopPackageLocked(final String packageName, int uid) {
5910        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5911                Uri.fromParts("package", packageName, null));
5912        if (!mProcessesReady) {
5913            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5914                    | Intent.FLAG_RECEIVER_FOREGROUND);
5915        }
5916        intent.putExtra(Intent.EXTRA_UID, uid);
5917        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5918        broadcastIntentLocked(null, null, intent,
5919                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5920                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5921    }
5922
5923
5924    private final boolean killPackageProcessesLocked(String packageName, int appId,
5925            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5926            boolean doit, boolean evenPersistent, String reason) {
5927        ArrayList<ProcessRecord> procs = new ArrayList<>();
5928
5929        // Remove all processes this package may have touched: all with the
5930        // same UID (except for the system or root user), and all whose name
5931        // matches the package name.
5932        final int NP = mProcessNames.getMap().size();
5933        for (int ip=0; ip<NP; ip++) {
5934            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5935            final int NA = apps.size();
5936            for (int ia=0; ia<NA; ia++) {
5937                ProcessRecord app = apps.valueAt(ia);
5938                if (app.persistent && !evenPersistent) {
5939                    // we don't kill persistent processes
5940                    continue;
5941                }
5942                if (app.removed) {
5943                    if (doit) {
5944                        procs.add(app);
5945                    }
5946                    continue;
5947                }
5948
5949                // Skip process if it doesn't meet our oom adj requirement.
5950                if (app.setAdj < minOomAdj) {
5951                    continue;
5952                }
5953
5954                // If no package is specified, we call all processes under the
5955                // give user id.
5956                if (packageName == null) {
5957                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5958                        continue;
5959                    }
5960                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5961                        continue;
5962                    }
5963                // Package has been specified, we want to hit all processes
5964                // that match it.  We need to qualify this by the processes
5965                // that are running under the specified app and user ID.
5966                } else {
5967                    final boolean isDep = app.pkgDeps != null
5968                            && app.pkgDeps.contains(packageName);
5969                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5970                        continue;
5971                    }
5972                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5973                        continue;
5974                    }
5975                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5976                        continue;
5977                    }
5978                }
5979
5980                // Process has passed all conditions, kill it!
5981                if (!doit) {
5982                    return true;
5983                }
5984                app.removed = true;
5985                procs.add(app);
5986            }
5987        }
5988
5989        int N = procs.size();
5990        for (int i=0; i<N; i++) {
5991            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5992        }
5993        updateOomAdjLocked();
5994        return N > 0;
5995    }
5996
5997    private void cleanupDisabledPackageComponentsLocked(
5998            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5999
6000        Set<String> disabledClasses = null;
6001        boolean packageDisabled = false;
6002        IPackageManager pm = AppGlobals.getPackageManager();
6003
6004        if (changedClasses == null) {
6005            // Nothing changed...
6006            return;
6007        }
6008
6009        // Determine enable/disable state of the package and its components.
6010        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6011        for (int i = changedClasses.length - 1; i >= 0; i--) {
6012            final String changedClass = changedClasses[i];
6013
6014            if (changedClass.equals(packageName)) {
6015                try {
6016                    // Entire package setting changed
6017                    enabled = pm.getApplicationEnabledSetting(packageName,
6018                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6019                } catch (Exception e) {
6020                    // No such package/component; probably racing with uninstall.  In any
6021                    // event it means we have nothing further to do here.
6022                    return;
6023                }
6024                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6025                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6026                if (packageDisabled) {
6027                    // Entire package is disabled.
6028                    // No need to continue to check component states.
6029                    disabledClasses = null;
6030                    break;
6031                }
6032            } else {
6033                try {
6034                    enabled = pm.getComponentEnabledSetting(
6035                            new ComponentName(packageName, changedClass),
6036                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6037                } catch (Exception e) {
6038                    // As above, probably racing with uninstall.
6039                    return;
6040                }
6041                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6042                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6043                    if (disabledClasses == null) {
6044                        disabledClasses = new ArraySet<>(changedClasses.length);
6045                    }
6046                    disabledClasses.add(changedClass);
6047                }
6048            }
6049        }
6050
6051        if (!packageDisabled && disabledClasses == null) {
6052            // Nothing to do here...
6053            return;
6054        }
6055
6056        // Clean-up disabled activities.
6057        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6058                packageName, disabledClasses, true, false, userId) && mBooted) {
6059            mStackSupervisor.resumeFocusedStackTopActivityLocked();
6060            mStackSupervisor.scheduleIdleLocked();
6061        }
6062
6063        // Clean-up disabled tasks
6064        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6065
6066        // Clean-up disabled services.
6067        mServices.bringDownDisabledPackageServicesLocked(
6068                packageName, disabledClasses, userId, false, killProcess, true);
6069
6070        // Clean-up disabled providers.
6071        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6072        mProviderMap.collectPackageProvidersLocked(
6073                packageName, disabledClasses, true, false, userId, providers);
6074        for (int i = providers.size() - 1; i >= 0; i--) {
6075            removeDyingProviderLocked(null, providers.get(i), true);
6076        }
6077
6078        // Clean-up disabled broadcast receivers.
6079        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6080            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6081                    packageName, disabledClasses, userId, true);
6082        }
6083
6084    }
6085
6086    final boolean clearBroadcastQueueForUserLocked(int userId) {
6087        boolean didSomething = false;
6088        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6089            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6090                    null, null, userId, true);
6091        }
6092        return didSomething;
6093    }
6094
6095    final boolean forceStopPackageLocked(String packageName, int appId,
6096            boolean callerWillRestart, boolean purgeCache, boolean doit,
6097            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6098        int i;
6099
6100        if (userId == UserHandle.USER_ALL && packageName == null) {
6101            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6102        }
6103
6104        if (appId < 0 && packageName != null) {
6105            try {
6106                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6107                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6108            } catch (RemoteException e) {
6109            }
6110        }
6111
6112        if (doit) {
6113            if (packageName != null) {
6114                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6115                        + " user=" + userId + ": " + reason);
6116            } else {
6117                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6118            }
6119
6120            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6121        }
6122
6123        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6124                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6125                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6126
6127        didSomething |= mActivityStarter.clearPendingActivityLaunchesLocked(packageName);
6128
6129        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6130                packageName, null, doit, evenPersistent, userId)) {
6131            if (!doit) {
6132                return true;
6133            }
6134            didSomething = true;
6135        }
6136
6137        if (mServices.bringDownDisabledPackageServicesLocked(
6138                packageName, null, userId, evenPersistent, true, doit)) {
6139            if (!doit) {
6140                return true;
6141            }
6142            didSomething = true;
6143        }
6144
6145        if (packageName == null) {
6146            // Remove all sticky broadcasts from this user.
6147            mStickyBroadcasts.remove(userId);
6148        }
6149
6150        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6151        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6152                userId, providers)) {
6153            if (!doit) {
6154                return true;
6155            }
6156            didSomething = true;
6157        }
6158        for (i = providers.size() - 1; i >= 0; i--) {
6159            removeDyingProviderLocked(null, providers.get(i), true);
6160        }
6161
6162        // Remove transient permissions granted from/to this package/user
6163        removeUriPermissionsForPackageLocked(packageName, userId, false);
6164
6165        if (doit) {
6166            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6167                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6168                        packageName, null, userId, doit);
6169            }
6170        }
6171
6172        if (packageName == null || uninstalling) {
6173            // Remove pending intents.  For now we only do this when force
6174            // stopping users, because we have some problems when doing this
6175            // for packages -- app widgets are not currently cleaned up for
6176            // such packages, so they can be left with bad pending intents.
6177            if (mIntentSenderRecords.size() > 0) {
6178                Iterator<WeakReference<PendingIntentRecord>> it
6179                        = mIntentSenderRecords.values().iterator();
6180                while (it.hasNext()) {
6181                    WeakReference<PendingIntentRecord> wpir = it.next();
6182                    if (wpir == null) {
6183                        it.remove();
6184                        continue;
6185                    }
6186                    PendingIntentRecord pir = wpir.get();
6187                    if (pir == null) {
6188                        it.remove();
6189                        continue;
6190                    }
6191                    if (packageName == null) {
6192                        // Stopping user, remove all objects for the user.
6193                        if (pir.key.userId != userId) {
6194                            // Not the same user, skip it.
6195                            continue;
6196                        }
6197                    } else {
6198                        if (UserHandle.getAppId(pir.uid) != appId) {
6199                            // Different app id, skip it.
6200                            continue;
6201                        }
6202                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6203                            // Different user, skip it.
6204                            continue;
6205                        }
6206                        if (!pir.key.packageName.equals(packageName)) {
6207                            // Different package, skip it.
6208                            continue;
6209                        }
6210                    }
6211                    if (!doit) {
6212                        return true;
6213                    }
6214                    didSomething = true;
6215                    it.remove();
6216                    pir.canceled = true;
6217                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6218                        pir.key.activity.pendingResults.remove(pir.ref);
6219                    }
6220                }
6221            }
6222        }
6223
6224        if (doit) {
6225            if (purgeCache && packageName != null) {
6226                AttributeCache ac = AttributeCache.instance();
6227                if (ac != null) {
6228                    ac.removePackage(packageName);
6229                }
6230            }
6231            if (mBooted) {
6232                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6233                mStackSupervisor.scheduleIdleLocked();
6234            }
6235        }
6236
6237        return didSomething;
6238    }
6239
6240    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6241        return removeProcessNameLocked(name, uid, null);
6242    }
6243
6244    private final ProcessRecord removeProcessNameLocked(final String name, final int uid,
6245            final ProcessRecord expecting) {
6246        ProcessRecord old = mProcessNames.get(name, uid);
6247        // Only actually remove when the currently recorded value matches the
6248        // record that we expected; if it doesn't match then we raced with a
6249        // newly created process and we don't want to destroy the new one.
6250        if ((expecting == null) || (old == expecting)) {
6251            mProcessNames.remove(name, uid);
6252        }
6253        if (old != null && old.uidRecord != null) {
6254            old.uidRecord.numProcs--;
6255            if (old.uidRecord.numProcs == 0) {
6256                // No more processes using this uid, tell clients it is gone.
6257                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6258                        "No more processes in " + old.uidRecord);
6259                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6260                mActiveUids.remove(uid);
6261                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6262            }
6263            old.uidRecord = null;
6264        }
6265        mIsolatedProcesses.remove(uid);
6266        return old;
6267    }
6268
6269    private final void addProcessNameLocked(ProcessRecord proc) {
6270        // We shouldn't already have a process under this name, but just in case we
6271        // need to clean up whatever may be there now.
6272        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6273        if (old == proc && proc.persistent) {
6274            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6275            Slog.w(TAG, "Re-adding persistent process " + proc);
6276        } else if (old != null) {
6277            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6278        }
6279        UidRecord uidRec = mActiveUids.get(proc.uid);
6280        if (uidRec == null) {
6281            uidRec = new UidRecord(proc.uid);
6282            // This is the first appearance of the uid, report it now!
6283            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6284                    "Creating new process uid: " + uidRec);
6285            mActiveUids.put(proc.uid, uidRec);
6286            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6287            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6288        }
6289        proc.uidRecord = uidRec;
6290
6291        // Reset render thread tid if it was already set, so new process can set it again.
6292        proc.renderThreadTid = 0;
6293        uidRec.numProcs++;
6294        mProcessNames.put(proc.processName, proc.uid, proc);
6295        if (proc.isolated) {
6296            mIsolatedProcesses.put(proc.uid, proc);
6297        }
6298    }
6299
6300    boolean removeProcessLocked(ProcessRecord app,
6301            boolean callerWillRestart, boolean allowRestart, String reason) {
6302        final String name = app.processName;
6303        final int uid = app.uid;
6304        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6305            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6306
6307        ProcessRecord old = mProcessNames.get(name, uid);
6308        if (old != app) {
6309            // This process is no longer active, so nothing to do.
6310            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6311            return false;
6312        }
6313        removeProcessNameLocked(name, uid);
6314        if (mHeavyWeightProcess == app) {
6315            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6316                    mHeavyWeightProcess.userId, 0));
6317            mHeavyWeightProcess = null;
6318        }
6319        boolean needRestart = false;
6320        if (app.pid > 0 && app.pid != MY_PID) {
6321            int pid = app.pid;
6322            synchronized (mPidsSelfLocked) {
6323                mPidsSelfLocked.remove(pid);
6324                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6325            }
6326            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6327            if (app.isolated) {
6328                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6329            }
6330            boolean willRestart = false;
6331            if (app.persistent && !app.isolated) {
6332                if (!callerWillRestart) {
6333                    willRestart = true;
6334                } else {
6335                    needRestart = true;
6336                }
6337            }
6338            app.kill(reason, true);
6339            handleAppDiedLocked(app, willRestart, allowRestart);
6340            if (willRestart) {
6341                removeLruProcessLocked(app);
6342                addAppLocked(app.info, false, null /* ABI override */);
6343            }
6344        } else {
6345            mRemovedProcesses.add(app);
6346        }
6347
6348        return needRestart;
6349    }
6350
6351    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6352        cleanupAppInLaunchingProvidersLocked(app, true);
6353        removeProcessLocked(app, false, true, "timeout publishing content providers");
6354    }
6355
6356    private final void processStartTimedOutLocked(ProcessRecord app) {
6357        final int pid = app.pid;
6358        boolean gone = false;
6359        synchronized (mPidsSelfLocked) {
6360            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6361            if (knownApp != null && knownApp.thread == null) {
6362                mPidsSelfLocked.remove(pid);
6363                gone = true;
6364            }
6365        }
6366
6367        if (gone) {
6368            Slog.w(TAG, "Process " + app + " failed to attach");
6369            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6370                    pid, app.uid, app.processName);
6371            removeProcessNameLocked(app.processName, app.uid);
6372            if (mHeavyWeightProcess == app) {
6373                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6374                        mHeavyWeightProcess.userId, 0));
6375                mHeavyWeightProcess = null;
6376            }
6377            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6378            if (app.isolated) {
6379                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6380            }
6381            // Take care of any launching providers waiting for this process.
6382            cleanupAppInLaunchingProvidersLocked(app, true);
6383            // Take care of any services that are waiting for the process.
6384            mServices.processStartTimedOutLocked(app);
6385            app.kill("start timeout", true);
6386            removeLruProcessLocked(app);
6387            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6388                Slog.w(TAG, "Unattached app died before backup, skipping");
6389                mHandler.post(new Runnable() {
6390                @Override
6391                    public void run(){
6392                        try {
6393                            IBackupManager bm = IBackupManager.Stub.asInterface(
6394                                    ServiceManager.getService(Context.BACKUP_SERVICE));
6395                            bm.agentDisconnected(app.info.packageName);
6396                        } catch (RemoteException e) {
6397                            // Can't happen; the backup manager is local
6398                        }
6399                    }
6400                });
6401            }
6402            if (isPendingBroadcastProcessLocked(pid)) {
6403                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6404                skipPendingBroadcastLocked(pid);
6405            }
6406        } else {
6407            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6408        }
6409    }
6410
6411    private final boolean attachApplicationLocked(IApplicationThread thread,
6412            int pid) {
6413
6414        // Find the application record that is being attached...  either via
6415        // the pid if we are running in multiple processes, or just pull the
6416        // next app record if we are emulating process with anonymous threads.
6417        ProcessRecord app;
6418        if (pid != MY_PID && pid >= 0) {
6419            synchronized (mPidsSelfLocked) {
6420                app = mPidsSelfLocked.get(pid);
6421            }
6422        } else {
6423            app = null;
6424        }
6425
6426        if (app == null) {
6427            Slog.w(TAG, "No pending application record for pid " + pid
6428                    + " (IApplicationThread " + thread + "); dropping process");
6429            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6430            if (pid > 0 && pid != MY_PID) {
6431                Process.killProcessQuiet(pid);
6432                //TODO: killProcessGroup(app.info.uid, pid);
6433            } else {
6434                try {
6435                    thread.scheduleExit();
6436                } catch (Exception e) {
6437                    // Ignore exceptions.
6438                }
6439            }
6440            return false;
6441        }
6442
6443        // If this application record is still attached to a previous
6444        // process, clean it up now.
6445        if (app.thread != null) {
6446            handleAppDiedLocked(app, true, true);
6447        }
6448
6449        // Tell the process all about itself.
6450
6451        if (DEBUG_ALL) Slog.v(
6452                TAG, "Binding process pid " + pid + " to record " + app);
6453
6454        final String processName = app.processName;
6455        try {
6456            AppDeathRecipient adr = new AppDeathRecipient(
6457                    app, pid, thread);
6458            thread.asBinder().linkToDeath(adr, 0);
6459            app.deathRecipient = adr;
6460        } catch (RemoteException e) {
6461            app.resetPackageList(mProcessStats);
6462            startProcessLocked(app, "link fail", processName);
6463            return false;
6464        }
6465
6466        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6467
6468        app.makeActive(thread, mProcessStats);
6469        app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6470        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6471        app.forcingToForeground = null;
6472        updateProcessForegroundLocked(app, false, false);
6473        app.hasShownUi = false;
6474        app.debugging = false;
6475        app.cached = false;
6476        app.killedByAm = false;
6477        app.killed = false;
6478
6479
6480        // We carefully use the same state that PackageManager uses for
6481        // filtering, since we use this flag to decide if we need to install
6482        // providers when user is unlocked later
6483        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6484
6485        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6486
6487        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6488        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6489
6490        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6491            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6492            msg.obj = app;
6493            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6494        }
6495
6496        if (!normalMode) {
6497            Slog.i(TAG, "Launching preboot mode app: " + app);
6498        }
6499
6500        if (DEBUG_ALL) Slog.v(
6501            TAG, "New app record " + app
6502            + " thread=" + thread.asBinder() + " pid=" + pid);
6503        try {
6504            int testMode = ApplicationThreadConstants.DEBUG_OFF;
6505            if (mDebugApp != null && mDebugApp.equals(processName)) {
6506                testMode = mWaitForDebugger
6507                    ? ApplicationThreadConstants.DEBUG_WAIT
6508                    : ApplicationThreadConstants.DEBUG_ON;
6509                app.debugging = true;
6510                if (mDebugTransient) {
6511                    mDebugApp = mOrigDebugApp;
6512                    mWaitForDebugger = mOrigWaitForDebugger;
6513                }
6514            }
6515            String profileFile = app.instrumentationProfileFile;
6516            ParcelFileDescriptor profileFd = null;
6517            int samplingInterval = 0;
6518            boolean profileAutoStop = false;
6519            if (mProfileApp != null && mProfileApp.equals(processName)) {
6520                mProfileProc = app;
6521                profileFile = mProfileFile;
6522                profileFd = mProfileFd;
6523                samplingInterval = mSamplingInterval;
6524                profileAutoStop = mAutoStopProfiler;
6525            }
6526            boolean enableTrackAllocation = false;
6527            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6528                enableTrackAllocation = true;
6529                mTrackAllocationApp = null;
6530            }
6531
6532            // If the app is being launched for restore or full backup, set it up specially
6533            boolean isRestrictedBackupMode = false;
6534            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6535                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6536                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6537                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6538                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6539            }
6540
6541            if (app.instrumentationClass != null) {
6542                notifyPackageUse(app.instrumentationClass.getPackageName(),
6543                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6544            }
6545            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6546                    + processName + " with config " + getGlobalConfiguration());
6547            ApplicationInfo appInfo = app.instrumentationInfo != null
6548                    ? app.instrumentationInfo : app.info;
6549            app.compat = compatibilityInfoForPackageLocked(appInfo);
6550            if (profileFd != null) {
6551                profileFd = profileFd.dup();
6552            }
6553            ProfilerInfo profilerInfo = profileFile == null ? null
6554                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6555
6556            // We deprecated Build.SERIAL and only apps that target pre NMR1
6557            // SDK can see it. Since access to the serial is now behind a
6558            // permission we push down the value.
6559            String buildSerial = Build.UNKNOWN;
6560            // TODO: SHTOPSHIP Uncomment the check when clients migrate
6561//            if (appInfo.targetSdkVersion <= Build.VERSION_CODES.N_MR1) {
6562                buildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
6563                        ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
6564                        .getSerial();
6565//            }
6566
6567            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6568                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6569                    app.instrumentationUiAutomationConnection, testMode,
6570                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6571                    isRestrictedBackupMode || !normalMode, app.persistent,
6572                    new Configuration(getGlobalConfiguration()), app.compat,
6573                    getCommonServicesLocked(app.isolated),
6574                    mCoreSettingsObserver.getCoreSettingsLocked(),
6575                    buildSerial);
6576
6577            updateLruProcessLocked(app, false, null);
6578            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6579        } catch (Exception e) {
6580            // todo: Yikes!  What should we do?  For now we will try to
6581            // start another process, but that could easily get us in
6582            // an infinite loop of restarting processes...
6583            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6584
6585            app.resetPackageList(mProcessStats);
6586            app.unlinkDeathRecipient();
6587            startProcessLocked(app, "bind fail", processName);
6588            return false;
6589        }
6590
6591        // Remove this record from the list of starting applications.
6592        mPersistentStartingProcesses.remove(app);
6593        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6594                "Attach application locked removing on hold: " + app);
6595        mProcessesOnHold.remove(app);
6596
6597        boolean badApp = false;
6598        boolean didSomething = false;
6599
6600        // See if the top visible activity is waiting to run in this process...
6601        if (normalMode) {
6602            try {
6603                if (mStackSupervisor.attachApplicationLocked(app)) {
6604                    didSomething = true;
6605                }
6606            } catch (Exception e) {
6607                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6608                badApp = true;
6609            }
6610        }
6611
6612        // Find any services that should be running in this process...
6613        if (!badApp) {
6614            try {
6615                didSomething |= mServices.attachApplicationLocked(app, processName);
6616            } catch (Exception e) {
6617                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6618                badApp = true;
6619            }
6620        }
6621
6622        // Check if a next-broadcast receiver is in this process...
6623        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6624            try {
6625                didSomething |= sendPendingBroadcastsLocked(app);
6626            } catch (Exception e) {
6627                // If the app died trying to launch the receiver we declare it 'bad'
6628                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6629                badApp = true;
6630            }
6631        }
6632
6633        // Check whether the next backup agent is in this process...
6634        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6635            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6636                    "New app is backup target, launching agent for " + app);
6637            notifyPackageUse(mBackupTarget.appInfo.packageName,
6638                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6639            try {
6640                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6641                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6642                        mBackupTarget.backupMode);
6643            } catch (Exception e) {
6644                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6645                badApp = true;
6646            }
6647        }
6648
6649        if (badApp) {
6650            app.kill("error during init", true);
6651            handleAppDiedLocked(app, false, true);
6652            return false;
6653        }
6654
6655        if (!didSomething) {
6656            updateOomAdjLocked();
6657        }
6658
6659        return true;
6660    }
6661
6662    @Override
6663    public final void attachApplication(IApplicationThread thread) {
6664        synchronized (this) {
6665            int callingPid = Binder.getCallingPid();
6666            final long origId = Binder.clearCallingIdentity();
6667            attachApplicationLocked(thread, callingPid);
6668            Binder.restoreCallingIdentity(origId);
6669        }
6670    }
6671
6672    @Override
6673    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6674        final long origId = Binder.clearCallingIdentity();
6675        synchronized (this) {
6676            ActivityStack stack = ActivityRecord.getStackLocked(token);
6677            if (stack != null) {
6678                ActivityRecord r =
6679                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6680                if (stopProfiling) {
6681                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6682                        try {
6683                            mProfileFd.close();
6684                        } catch (IOException e) {
6685                        }
6686                        clearProfilerLocked();
6687                    }
6688                }
6689            }
6690        }
6691        Binder.restoreCallingIdentity(origId);
6692    }
6693
6694    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6695        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6696                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6697    }
6698
6699    void enableScreenAfterBoot() {
6700        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6701                SystemClock.uptimeMillis());
6702        mWindowManager.enableScreenAfterBoot();
6703
6704        synchronized (this) {
6705            updateEventDispatchingLocked();
6706        }
6707    }
6708
6709    @Override
6710    public void showBootMessage(final CharSequence msg, final boolean always) {
6711        if (Binder.getCallingUid() != Process.myUid()) {
6712            throw new SecurityException();
6713        }
6714        mWindowManager.showBootMessage(msg, always);
6715    }
6716
6717    @Override
6718    public void keyguardGoingAway(int flags) {
6719        enforceNotIsolatedCaller("keyguardGoingAway");
6720        final long token = Binder.clearCallingIdentity();
6721        try {
6722            synchronized (this) {
6723                mKeyguardController.keyguardGoingAway(flags);
6724            }
6725        } finally {
6726            Binder.restoreCallingIdentity(token);
6727        }
6728    }
6729
6730    /**
6731     * @return whther the keyguard is currently locked.
6732     */
6733    boolean isKeyguardLocked() {
6734        return mKeyguardController.isKeyguardLocked();
6735    }
6736
6737    final void finishBooting() {
6738        synchronized (this) {
6739            if (!mBootAnimationComplete) {
6740                mCallFinishBooting = true;
6741                return;
6742            }
6743            mCallFinishBooting = false;
6744        }
6745
6746        ArraySet<String> completedIsas = new ArraySet<String>();
6747        for (String abi : Build.SUPPORTED_ABIS) {
6748            Process.zygoteProcess.establishZygoteConnectionForAbi(abi);
6749            final String instructionSet = VMRuntime.getInstructionSet(abi);
6750            if (!completedIsas.contains(instructionSet)) {
6751                try {
6752                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6753                } catch (InstallerException e) {
6754                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6755                            e.getMessage() +")");
6756                }
6757                completedIsas.add(instructionSet);
6758            }
6759        }
6760
6761        IntentFilter pkgFilter = new IntentFilter();
6762        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6763        pkgFilter.addDataScheme("package");
6764        mContext.registerReceiver(new BroadcastReceiver() {
6765            @Override
6766            public void onReceive(Context context, Intent intent) {
6767                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6768                if (pkgs != null) {
6769                    for (String pkg : pkgs) {
6770                        synchronized (ActivityManagerService.this) {
6771                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6772                                    0, "query restart")) {
6773                                setResultCode(Activity.RESULT_OK);
6774                                return;
6775                            }
6776                        }
6777                    }
6778                }
6779            }
6780        }, pkgFilter);
6781
6782        IntentFilter dumpheapFilter = new IntentFilter();
6783        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6784        mContext.registerReceiver(new BroadcastReceiver() {
6785            @Override
6786            public void onReceive(Context context, Intent intent) {
6787                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6788                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6789                } else {
6790                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6791                }
6792            }
6793        }, dumpheapFilter);
6794
6795        // Let system services know.
6796        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6797
6798        synchronized (this) {
6799            // Ensure that any processes we had put on hold are now started
6800            // up.
6801            final int NP = mProcessesOnHold.size();
6802            if (NP > 0) {
6803                ArrayList<ProcessRecord> procs =
6804                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6805                for (int ip=0; ip<NP; ip++) {
6806                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6807                            + procs.get(ip));
6808                    startProcessLocked(procs.get(ip), "on-hold", null);
6809                }
6810            }
6811
6812            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6813                // Start looking for apps that are abusing wake locks.
6814                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6815                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6816                // Tell anyone interested that we are done booting!
6817                SystemProperties.set("sys.boot_completed", "1");
6818
6819                // And trigger dev.bootcomplete if we are not showing encryption progress
6820                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6821                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6822                    SystemProperties.set("dev.bootcomplete", "1");
6823                }
6824                mUserController.sendBootCompletedLocked(
6825                        new IIntentReceiver.Stub() {
6826                            @Override
6827                            public void performReceive(Intent intent, int resultCode,
6828                                    String data, Bundle extras, boolean ordered,
6829                                    boolean sticky, int sendingUser) {
6830                                synchronized (ActivityManagerService.this) {
6831                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6832                                            true, false);
6833                                }
6834                            }
6835                        });
6836                scheduleStartProfilesLocked();
6837            }
6838        }
6839    }
6840
6841    @Override
6842    public void bootAnimationComplete() {
6843        final boolean callFinishBooting;
6844        synchronized (this) {
6845            callFinishBooting = mCallFinishBooting;
6846            mBootAnimationComplete = true;
6847        }
6848        if (callFinishBooting) {
6849            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6850            finishBooting();
6851            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6852        }
6853    }
6854
6855    final void ensureBootCompleted() {
6856        boolean booting;
6857        boolean enableScreen;
6858        synchronized (this) {
6859            booting = mBooting;
6860            mBooting = false;
6861            enableScreen = !mBooted;
6862            mBooted = true;
6863        }
6864
6865        if (booting) {
6866            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6867            finishBooting();
6868            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6869        }
6870
6871        if (enableScreen) {
6872            enableScreenAfterBoot();
6873        }
6874    }
6875
6876    @Override
6877    public final void activityResumed(IBinder token) {
6878        final long origId = Binder.clearCallingIdentity();
6879        synchronized(this) {
6880            ActivityRecord.activityResumedLocked(token);
6881            mWindowManager.notifyAppResumedFinished(token);
6882        }
6883        Binder.restoreCallingIdentity(origId);
6884    }
6885
6886    @Override
6887    public final void activityPaused(IBinder token) {
6888        final long origId = Binder.clearCallingIdentity();
6889        synchronized(this) {
6890            ActivityStack stack = ActivityRecord.getStackLocked(token);
6891            if (stack != null) {
6892                stack.activityPausedLocked(token, false);
6893            }
6894        }
6895        Binder.restoreCallingIdentity(origId);
6896    }
6897
6898    @Override
6899    public final void activityStopped(IBinder token, Bundle icicle,
6900            PersistableBundle persistentState, CharSequence description) {
6901        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6902
6903        // Refuse possible leaked file descriptors
6904        if (icicle != null && icicle.hasFileDescriptors()) {
6905            throw new IllegalArgumentException("File descriptors passed in Bundle");
6906        }
6907
6908        final long origId = Binder.clearCallingIdentity();
6909
6910        synchronized (this) {
6911            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
6912            if (r != null) {
6913                r.activityStoppedLocked(icicle, persistentState, description);
6914            }
6915        }
6916
6917        trimApplications();
6918
6919        Binder.restoreCallingIdentity(origId);
6920    }
6921
6922    @Override
6923    public final void activityDestroyed(IBinder token) {
6924        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6925        synchronized (this) {
6926            ActivityStack stack = ActivityRecord.getStackLocked(token);
6927            if (stack != null) {
6928                stack.activityDestroyedLocked(token, "activityDestroyed");
6929            }
6930        }
6931    }
6932
6933    @Override
6934    public final void activityRelaunched(IBinder token) {
6935        final long origId = Binder.clearCallingIdentity();
6936        synchronized (this) {
6937            mStackSupervisor.activityRelaunchedLocked(token);
6938        }
6939        Binder.restoreCallingIdentity(origId);
6940    }
6941
6942    @Override
6943    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6944            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6945        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6946                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6947        synchronized (this) {
6948            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6949            if (record == null) {
6950                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6951                        + "found for: " + token);
6952            }
6953            record.setSizeConfigurations(horizontalSizeConfiguration,
6954                    verticalSizeConfigurations, smallestSizeConfigurations);
6955        }
6956    }
6957
6958    @Override
6959    public final void backgroundResourcesReleased(IBinder token) {
6960        final long origId = Binder.clearCallingIdentity();
6961        try {
6962            synchronized (this) {
6963                ActivityStack stack = ActivityRecord.getStackLocked(token);
6964                if (stack != null) {
6965                    stack.backgroundResourcesReleased();
6966                }
6967            }
6968        } finally {
6969            Binder.restoreCallingIdentity(origId);
6970        }
6971    }
6972
6973    @Override
6974    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6975        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6976    }
6977
6978    @Override
6979    public final void notifyEnterAnimationComplete(IBinder token) {
6980        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6981    }
6982
6983    @Override
6984    public String getCallingPackage(IBinder token) {
6985        synchronized (this) {
6986            ActivityRecord r = getCallingRecordLocked(token);
6987            return r != null ? r.info.packageName : null;
6988        }
6989    }
6990
6991    @Override
6992    public ComponentName getCallingActivity(IBinder token) {
6993        synchronized (this) {
6994            ActivityRecord r = getCallingRecordLocked(token);
6995            return r != null ? r.intent.getComponent() : null;
6996        }
6997    }
6998
6999    private ActivityRecord getCallingRecordLocked(IBinder token) {
7000        ActivityRecord r = ActivityRecord.isInStackLocked(token);
7001        if (r == null) {
7002            return null;
7003        }
7004        return r.resultTo;
7005    }
7006
7007    @Override
7008    public ComponentName getActivityClassForToken(IBinder token) {
7009        synchronized(this) {
7010            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7011            if (r == null) {
7012                return null;
7013            }
7014            return r.intent.getComponent();
7015        }
7016    }
7017
7018    @Override
7019    public String getPackageForToken(IBinder token) {
7020        synchronized(this) {
7021            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7022            if (r == null) {
7023                return null;
7024            }
7025            return r.packageName;
7026        }
7027    }
7028
7029    @Override
7030    public boolean isRootVoiceInteraction(IBinder token) {
7031        synchronized(this) {
7032            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7033            if (r == null) {
7034                return false;
7035            }
7036            return r.rootVoiceInteraction;
7037        }
7038    }
7039
7040    @Override
7041    public IIntentSender getIntentSender(int type,
7042            String packageName, IBinder token, String resultWho,
7043            int requestCode, Intent[] intents, String[] resolvedTypes,
7044            int flags, Bundle bOptions, int userId) {
7045        enforceNotIsolatedCaller("getIntentSender");
7046        // Refuse possible leaked file descriptors
7047        if (intents != null) {
7048            if (intents.length < 1) {
7049                throw new IllegalArgumentException("Intents array length must be >= 1");
7050            }
7051            for (int i=0; i<intents.length; i++) {
7052                Intent intent = intents[i];
7053                if (intent != null) {
7054                    if (intent.hasFileDescriptors()) {
7055                        throw new IllegalArgumentException("File descriptors passed in Intent");
7056                    }
7057                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7058                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7059                        throw new IllegalArgumentException(
7060                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7061                    }
7062                    intents[i] = new Intent(intent);
7063                }
7064            }
7065            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7066                throw new IllegalArgumentException(
7067                        "Intent array length does not match resolvedTypes length");
7068            }
7069        }
7070        if (bOptions != null) {
7071            if (bOptions.hasFileDescriptors()) {
7072                throw new IllegalArgumentException("File descriptors passed in options");
7073            }
7074        }
7075
7076        synchronized(this) {
7077            int callingUid = Binder.getCallingUid();
7078            int origUserId = userId;
7079            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7080                    type == ActivityManager.INTENT_SENDER_BROADCAST,
7081                    ALLOW_NON_FULL, "getIntentSender", null);
7082            if (origUserId == UserHandle.USER_CURRENT) {
7083                // We don't want to evaluate this until the pending intent is
7084                // actually executed.  However, we do want to always do the
7085                // security checking for it above.
7086                userId = UserHandle.USER_CURRENT;
7087            }
7088            try {
7089                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
7090                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7091                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7092                    if (!UserHandle.isSameApp(callingUid, uid)) {
7093                        String msg = "Permission Denial: getIntentSender() from pid="
7094                            + Binder.getCallingPid()
7095                            + ", uid=" + Binder.getCallingUid()
7096                            + ", (need uid=" + uid + ")"
7097                            + " is not allowed to send as package " + packageName;
7098                        Slog.w(TAG, msg);
7099                        throw new SecurityException(msg);
7100                    }
7101                }
7102
7103                return getIntentSenderLocked(type, packageName, callingUid, userId,
7104                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7105
7106            } catch (RemoteException e) {
7107                throw new SecurityException(e);
7108            }
7109        }
7110    }
7111
7112    IIntentSender getIntentSenderLocked(int type, String packageName,
7113            int callingUid, int userId, IBinder token, String resultWho,
7114            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7115            Bundle bOptions) {
7116        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7117        ActivityRecord activity = null;
7118        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7119            activity = ActivityRecord.isInStackLocked(token);
7120            if (activity == null) {
7121                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7122                return null;
7123            }
7124            if (activity.finishing) {
7125                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7126                return null;
7127            }
7128        }
7129
7130        // We're going to be splicing together extras before sending, so we're
7131        // okay poking into any contained extras.
7132        if (intents != null) {
7133            for (int i = 0; i < intents.length; i++) {
7134                intents[i].setDefusable(true);
7135            }
7136        }
7137        Bundle.setDefusable(bOptions, true);
7138
7139        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7140        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7141        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7142        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7143                |PendingIntent.FLAG_UPDATE_CURRENT);
7144
7145        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7146                type, packageName, activity, resultWho,
7147                requestCode, intents, resolvedTypes, flags, bOptions, userId);
7148        WeakReference<PendingIntentRecord> ref;
7149        ref = mIntentSenderRecords.get(key);
7150        PendingIntentRecord rec = ref != null ? ref.get() : null;
7151        if (rec != null) {
7152            if (!cancelCurrent) {
7153                if (updateCurrent) {
7154                    if (rec.key.requestIntent != null) {
7155                        rec.key.requestIntent.replaceExtras(intents != null ?
7156                                intents[intents.length - 1] : null);
7157                    }
7158                    if (intents != null) {
7159                        intents[intents.length-1] = rec.key.requestIntent;
7160                        rec.key.allIntents = intents;
7161                        rec.key.allResolvedTypes = resolvedTypes;
7162                    } else {
7163                        rec.key.allIntents = null;
7164                        rec.key.allResolvedTypes = null;
7165                    }
7166                }
7167                return rec;
7168            }
7169            rec.canceled = true;
7170            mIntentSenderRecords.remove(key);
7171        }
7172        if (noCreate) {
7173            return rec;
7174        }
7175        rec = new PendingIntentRecord(this, key, callingUid);
7176        mIntentSenderRecords.put(key, rec.ref);
7177        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7178            if (activity.pendingResults == null) {
7179                activity.pendingResults
7180                        = new HashSet<WeakReference<PendingIntentRecord>>();
7181            }
7182            activity.pendingResults.add(rec.ref);
7183        }
7184        return rec;
7185    }
7186
7187    @Override
7188    public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7189            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7190        if (target instanceof PendingIntentRecord) {
7191            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7192                    finishedReceiver, requiredPermission, options);
7193        } else {
7194            if (intent == null) {
7195                // Weird case: someone has given us their own custom IIntentSender, and now
7196                // they have someone else trying to send to it but of course this isn't
7197                // really a PendingIntent, so there is no base Intent, and the caller isn't
7198                // supplying an Intent... but we never want to dispatch a null Intent to
7199                // a receiver, so um...  let's make something up.
7200                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7201                intent = new Intent(Intent.ACTION_MAIN);
7202            }
7203            try {
7204                target.send(code, intent, resolvedType, null, requiredPermission, options);
7205            } catch (RemoteException e) {
7206            }
7207            // Platform code can rely on getting a result back when the send is done, but if
7208            // this intent sender is from outside of the system we can't rely on it doing that.
7209            // So instead we don't give it the result receiver, and instead just directly
7210            // report the finish immediately.
7211            if (finishedReceiver != null) {
7212                try {
7213                    finishedReceiver.performReceive(intent, 0,
7214                            null, null, false, false, UserHandle.getCallingUserId());
7215                } catch (RemoteException e) {
7216                }
7217            }
7218            return 0;
7219        }
7220    }
7221
7222    /**
7223     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
7224     *
7225     * <p>{@code callerUid} must be allowed to request such whitelist by calling
7226     * {@link #addTempPowerSaveWhitelistGrantorUid(int)}.
7227     */
7228    void tempWhitelistAppForPowerSave(int callerPid, int callerUid, int targetUid, long duration) {
7229        if (DEBUG_WHITELISTS) {
7230            Slog.d(TAG, "tempWhitelistAppForPowerSave(" + callerPid + ", " + callerUid + ", "
7231                    + targetUid + ", " + duration + ")");
7232        }
7233        synchronized (mPidsSelfLocked) {
7234            final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
7235            if (pr == null) {
7236                Slog.w(TAG, "tempWhitelistAppForPowerSave() no ProcessRecord for pid " + callerPid);
7237                return;
7238            }
7239            if (!pr.whitelistManager) {
7240                if (DEBUG_WHITELISTS) {
7241                    Slog.d(TAG, "tempWhitelistAppForPowerSave() for target " + targetUid + ": pid "
7242                            + callerPid + " is not allowed");
7243                }
7244                return;
7245            }
7246        }
7247
7248        final long token = Binder.clearCallingIdentity();
7249        try {
7250            mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(targetUid, duration,
7251                    true, "pe from uid:" + callerUid);
7252        } finally {
7253            Binder.restoreCallingIdentity(token);
7254        }
7255    }
7256
7257    @Override
7258    public void cancelIntentSender(IIntentSender sender) {
7259        if (!(sender instanceof PendingIntentRecord)) {
7260            return;
7261        }
7262        synchronized(this) {
7263            PendingIntentRecord rec = (PendingIntentRecord)sender;
7264            try {
7265                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7266                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7267                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7268                    String msg = "Permission Denial: cancelIntentSender() from pid="
7269                        + Binder.getCallingPid()
7270                        + ", uid=" + Binder.getCallingUid()
7271                        + " is not allowed to cancel packges "
7272                        + rec.key.packageName;
7273                    Slog.w(TAG, msg);
7274                    throw new SecurityException(msg);
7275                }
7276            } catch (RemoteException e) {
7277                throw new SecurityException(e);
7278            }
7279            cancelIntentSenderLocked(rec, true);
7280        }
7281    }
7282
7283    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7284        rec.canceled = true;
7285        mIntentSenderRecords.remove(rec.key);
7286        if (cleanActivity && rec.key.activity != null) {
7287            rec.key.activity.pendingResults.remove(rec.ref);
7288        }
7289    }
7290
7291    @Override
7292    public String getPackageForIntentSender(IIntentSender pendingResult) {
7293        if (!(pendingResult instanceof PendingIntentRecord)) {
7294            return null;
7295        }
7296        try {
7297            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7298            return res.key.packageName;
7299        } catch (ClassCastException e) {
7300        }
7301        return null;
7302    }
7303
7304    @Override
7305    public int getUidForIntentSender(IIntentSender sender) {
7306        if (sender instanceof PendingIntentRecord) {
7307            try {
7308                PendingIntentRecord res = (PendingIntentRecord)sender;
7309                return res.uid;
7310            } catch (ClassCastException e) {
7311            }
7312        }
7313        return -1;
7314    }
7315
7316    @Override
7317    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7318        if (!(pendingResult instanceof PendingIntentRecord)) {
7319            return false;
7320        }
7321        try {
7322            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7323            if (res.key.allIntents == null) {
7324                return false;
7325            }
7326            for (int i=0; i<res.key.allIntents.length; i++) {
7327                Intent intent = res.key.allIntents[i];
7328                if (intent.getPackage() != null && intent.getComponent() != null) {
7329                    return false;
7330                }
7331            }
7332            return true;
7333        } catch (ClassCastException e) {
7334        }
7335        return false;
7336    }
7337
7338    @Override
7339    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7340        if (!(pendingResult instanceof PendingIntentRecord)) {
7341            return false;
7342        }
7343        try {
7344            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7345            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7346                return true;
7347            }
7348            return false;
7349        } catch (ClassCastException e) {
7350        }
7351        return false;
7352    }
7353
7354    @Override
7355    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7356        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7357                "getIntentForIntentSender()");
7358        if (!(pendingResult instanceof PendingIntentRecord)) {
7359            return null;
7360        }
7361        try {
7362            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7363            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7364        } catch (ClassCastException e) {
7365        }
7366        return null;
7367    }
7368
7369    @Override
7370    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7371        if (!(pendingResult instanceof PendingIntentRecord)) {
7372            return null;
7373        }
7374        try {
7375            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7376            synchronized (this) {
7377                return getTagForIntentSenderLocked(res, prefix);
7378            }
7379        } catch (ClassCastException e) {
7380        }
7381        return null;
7382    }
7383
7384    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7385        final Intent intent = res.key.requestIntent;
7386        if (intent != null) {
7387            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7388                    || res.lastTagPrefix.equals(prefix))) {
7389                return res.lastTag;
7390            }
7391            res.lastTagPrefix = prefix;
7392            final StringBuilder sb = new StringBuilder(128);
7393            if (prefix != null) {
7394                sb.append(prefix);
7395            }
7396            if (intent.getAction() != null) {
7397                sb.append(intent.getAction());
7398            } else if (intent.getComponent() != null) {
7399                intent.getComponent().appendShortString(sb);
7400            } else {
7401                sb.append("?");
7402            }
7403            return res.lastTag = sb.toString();
7404        }
7405        return null;
7406    }
7407
7408    @Override
7409    public void setProcessLimit(int max) {
7410        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7411                "setProcessLimit()");
7412        synchronized (this) {
7413            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7414            mProcessLimitOverride = max;
7415        }
7416        trimApplications();
7417    }
7418
7419    @Override
7420    public int getProcessLimit() {
7421        synchronized (this) {
7422            return mProcessLimitOverride;
7423        }
7424    }
7425
7426    void foregroundTokenDied(ForegroundToken token) {
7427        synchronized (ActivityManagerService.this) {
7428            synchronized (mPidsSelfLocked) {
7429                ForegroundToken cur
7430                    = mForegroundProcesses.get(token.pid);
7431                if (cur != token) {
7432                    return;
7433                }
7434                mForegroundProcesses.remove(token.pid);
7435                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7436                if (pr == null) {
7437                    return;
7438                }
7439                pr.forcingToForeground = null;
7440                updateProcessForegroundLocked(pr, false, false);
7441            }
7442            updateOomAdjLocked();
7443        }
7444    }
7445
7446    @Override
7447    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7448        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7449                "setProcessForeground()");
7450        synchronized(this) {
7451            boolean changed = false;
7452
7453            synchronized (mPidsSelfLocked) {
7454                ProcessRecord pr = mPidsSelfLocked.get(pid);
7455                if (pr == null && isForeground) {
7456                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7457                    return;
7458                }
7459                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7460                if (oldToken != null) {
7461                    oldToken.token.unlinkToDeath(oldToken, 0);
7462                    mForegroundProcesses.remove(pid);
7463                    if (pr != null) {
7464                        pr.forcingToForeground = null;
7465                    }
7466                    changed = true;
7467                }
7468                if (isForeground && token != null) {
7469                    ForegroundToken newToken = new ForegroundToken() {
7470                        @Override
7471                        public void binderDied() {
7472                            foregroundTokenDied(this);
7473                        }
7474                    };
7475                    newToken.pid = pid;
7476                    newToken.token = token;
7477                    try {
7478                        token.linkToDeath(newToken, 0);
7479                        mForegroundProcesses.put(pid, newToken);
7480                        pr.forcingToForeground = token;
7481                        changed = true;
7482                    } catch (RemoteException e) {
7483                        // If the process died while doing this, we will later
7484                        // do the cleanup with the process death link.
7485                    }
7486                }
7487            }
7488
7489            if (changed) {
7490                updateOomAdjLocked();
7491            }
7492        }
7493    }
7494
7495    @Override
7496    public boolean isAppForeground(int uid) throws RemoteException {
7497        synchronized (this) {
7498            UidRecord uidRec = mActiveUids.get(uid);
7499            if (uidRec == null || uidRec.idle) {
7500                return false;
7501            }
7502            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7503        }
7504    }
7505
7506    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7507    // be guarded by permission checking.
7508    int getUidState(int uid) {
7509        synchronized (this) {
7510            UidRecord uidRec = mActiveUids.get(uid);
7511            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7512        }
7513    }
7514
7515    @Override
7516    public boolean isInMultiWindowMode(IBinder token) {
7517        final long origId = Binder.clearCallingIdentity();
7518        try {
7519            synchronized(this) {
7520                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7521                if (r == null) {
7522                    return false;
7523                }
7524                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7525                return !r.task.mFullscreen;
7526            }
7527        } finally {
7528            Binder.restoreCallingIdentity(origId);
7529        }
7530    }
7531
7532    @Override
7533    public boolean isInPictureInPictureMode(IBinder token) {
7534        final long origId = Binder.clearCallingIdentity();
7535        try {
7536            synchronized(this) {
7537                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7538                if (stack == null) {
7539                    return false;
7540                }
7541                return stack.mStackId == PINNED_STACK_ID;
7542            }
7543        } finally {
7544            Binder.restoreCallingIdentity(origId);
7545        }
7546    }
7547
7548    @Override
7549    public void enterPictureInPictureMode(IBinder token) {
7550        enterPictureInPictureMode(token, DEFAULT_DISPLAY, -1f /* aspectRatio */,
7551                false /* checkAspectRatio */);
7552    }
7553
7554    @Override
7555    public void enterPictureInPictureModeWithAspectRatio(IBinder token, float aspectRatio) {
7556        enterPictureInPictureMode(token, DEFAULT_DISPLAY, aspectRatio, true /* checkAspectRatio */);
7557    }
7558
7559    @Override
7560    public void enterPictureInPictureModeOnMoveToBackground(IBinder token,
7561            boolean enterPictureInPictureOnMoveToBg) {
7562        final long origId = Binder.clearCallingIdentity();
7563        try {
7564            synchronized(this) {
7565                final ActivityRecord r = ensureValidPictureInPictureActivityLocked(
7566                        "enterPictureInPictureModeOnMoveToBackground", token, -1f /* aspectRatio */,
7567                        false /* checkAspectRatio */, false /* checkActivityVisibility */);
7568
7569                r.supportsPipOnMoveToBackground = enterPictureInPictureOnMoveToBg;
7570            }
7571        } finally {
7572            Binder.restoreCallingIdentity(origId);
7573        }
7574    }
7575
7576    private void enterPictureInPictureMode(IBinder token, int displayId, float aspectRatio,
7577            boolean checkAspectRatio) {
7578        final long origId = Binder.clearCallingIdentity();
7579        try {
7580            synchronized(this) {
7581                final ActivityRecord r = ensureValidPictureInPictureActivityLocked(
7582                        "enterPictureInPictureMode", token, aspectRatio, checkAspectRatio,
7583                        true /* checkActivityVisibility */);
7584                final Runnable enterPipRunnable = () -> {
7585                    r.pictureInPictureArgs.aspectRatio = aspectRatio;
7586                    enterPictureInPictureModeLocked(r, displayId, r.pictureInPictureArgs,
7587                            true /* moveHomeStackToFront */, "enterPictureInPictureMode");
7588                };
7589
7590                if (isKeyguardLocked()) {
7591                    // If the keyguard is showing or occluded, then try and dismiss it before
7592                    // entering picture-in-picture (this will prompt the user to authenticate if the
7593                    // device is currently locked).
7594                    try {
7595                        dismissKeyguard(token, new IKeyguardDismissCallback.Stub() {
7596                            @Override
7597                            public void onDismissError() throws RemoteException {
7598                                // Do nothing
7599                            }
7600
7601                            @Override
7602                            public void onDismissSucceeded() throws RemoteException {
7603                                mHandler.post(enterPipRunnable);
7604                            }
7605
7606                            @Override
7607                            public void onDismissCancelled() throws RemoteException {
7608                                // Do nothing
7609                            }
7610                        });
7611                    } catch (RemoteException e) {
7612                        // Local call
7613                    }
7614                } else {
7615                    // Enter picture in picture immediately otherwise
7616                    enterPipRunnable.run();
7617                }
7618            }
7619        } finally {
7620            Binder.restoreCallingIdentity(origId);
7621        }
7622    }
7623
7624    void enterPictureInPictureModeLocked(ActivityRecord r, int displayId,
7625            PictureInPictureArguments pipArgs, boolean moveHomeStackToFront, String reason) {
7626        final Rect bounds = isValidPictureInPictureAspectRatio(pipArgs.aspectRatio)
7627                ? mWindowManager.getPictureInPictureBounds(displayId, pipArgs.aspectRatio)
7628                : mWindowManager.getPictureInPictureDefaultBounds(displayId);
7629        mStackSupervisor.moveActivityToPinnedStackLocked(r, reason, bounds, moveHomeStackToFront);
7630        mWindowManager.setPictureInPictureActions(pipArgs.userActions);
7631    }
7632
7633    @Override
7634    public void setPictureInPictureAspectRatio(IBinder token, float aspectRatio) {
7635        final long origId = Binder.clearCallingIdentity();
7636        try {
7637            synchronized(this) {
7638                final ActivityRecord r = ensureValidPictureInPictureActivityLocked(
7639                        "setPictureInPictureAspectRatio", token, aspectRatio,
7640                        true /* checkAspectRatio */, false /* checkActivityVisibility */);
7641
7642                r.pictureInPictureArgs.aspectRatio = aspectRatio;
7643                if (r.getStack().getStackId() == PINNED_STACK_ID) {
7644                    // If the activity is already in picture-in-picture, update the pinned stack now
7645                    mWindowManager.setPictureInPictureAspectRatio(aspectRatio);
7646                }
7647            }
7648        } finally {
7649            Binder.restoreCallingIdentity(origId);
7650        }
7651    }
7652
7653    @Override
7654    public void setPictureInPictureActions(IBinder token, ParceledListSlice actionsList) {
7655        final long origId = Binder.clearCallingIdentity();
7656        try {
7657            synchronized(this) {
7658                final ActivityRecord r = ensureValidPictureInPictureActivityLocked(
7659                        "setPictureInPictureActions", token, -1 /* aspectRatio */,
7660                        false /* checkAspectRatio */, false /* checkActivityVisibility */);
7661
7662                final List<RemoteAction> actions = actionsList.getList();
7663                if (actions.size() > ActivityManager.getMaxNumPictureInPictureActions()) {
7664                    throw new IllegalArgumentException("setPictureInPictureActions: Invalid number"
7665                            + " of picture-in-picture actions.  Only a maximum of "
7666                            + ActivityManager.getMaxNumPictureInPictureActions()
7667                            + " actions allowed");
7668                }
7669
7670                r.pictureInPictureArgs.userActions = actions;
7671                if (r.getStack().getStackId() == PINNED_STACK_ID) {
7672                    // If the activity is already in picture-in-picture, update the pinned stack now
7673                    mWindowManager.setPictureInPictureActions(actions);
7674                }
7675            }
7676        } finally {
7677            Binder.restoreCallingIdentity(origId);
7678        }
7679    }
7680
7681    private boolean isValidPictureInPictureAspectRatio(float aspectRatio) {
7682        return mMinPipAspectRatio <= aspectRatio && aspectRatio <= mMaxPipAspectRatio;
7683    }
7684
7685    /**
7686     * Checks the state of the system and the activity associated with the given {@param token} to
7687     * verify that picture-in-picture is supported for that activity.
7688     *
7689     * @param checkAspectRatio whether or not to check {@param aspectRatio} is within a valid range
7690     * @param checkActivityVisibility whether or not to enforce that the activity is currently
7691     *                                visible
7692     *
7693     * @return the activity record for the given {@param token} if all the checks pass.
7694     */
7695    private ActivityRecord ensureValidPictureInPictureActivityLocked(String caller, IBinder token,
7696            float aspectRatio, boolean checkAspectRatio, boolean checkActivityVisibility) {
7697        if (!mSupportsPictureInPicture) {
7698            throw new IllegalStateException(caller
7699                    + ": Device doesn't support picture-in-picture mode.");
7700        }
7701
7702        final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7703        if (r == null) {
7704            throw new IllegalStateException(caller
7705                    + ": Can't find activity for token=" + token);
7706        }
7707
7708        if (!r.canEnterPictureInPicture(checkActivityVisibility)) {
7709            throw new IllegalArgumentException(caller
7710                    + ": Current activity does not support picture-in-picture or is not "
7711                    + "visible r=" + r);
7712        }
7713
7714        if (r.getStack().isHomeStack()) {
7715            throw new IllegalStateException(caller
7716                    + ": Activities on the home stack not supported");
7717        }
7718
7719        if (checkAspectRatio && !isValidPictureInPictureAspectRatio(aspectRatio)) {
7720            throw new IllegalArgumentException(String.format(caller
7721                    + ": Aspect ratio is too extreme (must be between %f and %f).",
7722                            mMinPipAspectRatio, mMaxPipAspectRatio));
7723        }
7724
7725        return r;
7726    }
7727
7728    // =========================================================
7729    // PROCESS INFO
7730    // =========================================================
7731
7732    static class ProcessInfoService extends IProcessInfoService.Stub {
7733        final ActivityManagerService mActivityManagerService;
7734        ProcessInfoService(ActivityManagerService activityManagerService) {
7735            mActivityManagerService = activityManagerService;
7736        }
7737
7738        @Override
7739        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7740            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7741                    /*in*/ pids, /*out*/ states, null);
7742        }
7743
7744        @Override
7745        public void getProcessStatesAndOomScoresFromPids(
7746                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7747            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7748                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7749        }
7750    }
7751
7752    /**
7753     * For each PID in the given input array, write the current process state
7754     * for that process into the states array, or -1 to indicate that no
7755     * process with the given PID exists. If scores array is provided, write
7756     * the oom score for the process into the scores array, with INVALID_ADJ
7757     * indicating the PID doesn't exist.
7758     */
7759    public void getProcessStatesAndOomScoresForPIDs(
7760            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7761        if (scores != null) {
7762            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7763                    "getProcessStatesAndOomScoresForPIDs()");
7764        }
7765
7766        if (pids == null) {
7767            throw new NullPointerException("pids");
7768        } else if (states == null) {
7769            throw new NullPointerException("states");
7770        } else if (pids.length != states.length) {
7771            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7772        } else if (scores != null && pids.length != scores.length) {
7773            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7774        }
7775
7776        synchronized (mPidsSelfLocked) {
7777            for (int i = 0; i < pids.length; i++) {
7778                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7779                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7780                        pr.curProcState;
7781                if (scores != null) {
7782                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7783                }
7784            }
7785        }
7786    }
7787
7788    // =========================================================
7789    // PERMISSIONS
7790    // =========================================================
7791
7792    static class PermissionController extends IPermissionController.Stub {
7793        ActivityManagerService mActivityManagerService;
7794        PermissionController(ActivityManagerService activityManagerService) {
7795            mActivityManagerService = activityManagerService;
7796        }
7797
7798        @Override
7799        public boolean checkPermission(String permission, int pid, int uid) {
7800            return mActivityManagerService.checkPermission(permission, pid,
7801                    uid) == PackageManager.PERMISSION_GRANTED;
7802        }
7803
7804        @Override
7805        public String[] getPackagesForUid(int uid) {
7806            return mActivityManagerService.mContext.getPackageManager()
7807                    .getPackagesForUid(uid);
7808        }
7809
7810        @Override
7811        public boolean isRuntimePermission(String permission) {
7812            try {
7813                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7814                        .getPermissionInfo(permission, 0);
7815                return (info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
7816                        == PermissionInfo.PROTECTION_DANGEROUS;
7817            } catch (NameNotFoundException nnfe) {
7818                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7819            }
7820            return false;
7821        }
7822    }
7823
7824    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7825        @Override
7826        public int checkComponentPermission(String permission, int pid, int uid,
7827                int owningUid, boolean exported) {
7828            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7829                    owningUid, exported);
7830        }
7831
7832        @Override
7833        public Object getAMSLock() {
7834            return ActivityManagerService.this;
7835        }
7836    }
7837
7838    /**
7839     * This can be called with or without the global lock held.
7840     */
7841    int checkComponentPermission(String permission, int pid, int uid,
7842            int owningUid, boolean exported) {
7843        if (pid == MY_PID) {
7844            return PackageManager.PERMISSION_GRANTED;
7845        }
7846        return ActivityManager.checkComponentPermission(permission, uid,
7847                owningUid, exported);
7848    }
7849
7850    /**
7851     * As the only public entry point for permissions checking, this method
7852     * can enforce the semantic that requesting a check on a null global
7853     * permission is automatically denied.  (Internally a null permission
7854     * string is used when calling {@link #checkComponentPermission} in cases
7855     * when only uid-based security is needed.)
7856     *
7857     * This can be called with or without the global lock held.
7858     */
7859    @Override
7860    public int checkPermission(String permission, int pid, int uid) {
7861        if (permission == null) {
7862            return PackageManager.PERMISSION_DENIED;
7863        }
7864        return checkComponentPermission(permission, pid, uid, -1, true);
7865    }
7866
7867    @Override
7868    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7869        if (permission == null) {
7870            return PackageManager.PERMISSION_DENIED;
7871        }
7872
7873        // We might be performing an operation on behalf of an indirect binder
7874        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7875        // client identity accordingly before proceeding.
7876        Identity tlsIdentity = sCallerIdentity.get();
7877        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7878            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7879                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7880            uid = tlsIdentity.uid;
7881            pid = tlsIdentity.pid;
7882        }
7883
7884        return checkComponentPermission(permission, pid, uid, -1, true);
7885    }
7886
7887    /**
7888     * Binder IPC calls go through the public entry point.
7889     * This can be called with or without the global lock held.
7890     */
7891    int checkCallingPermission(String permission) {
7892        return checkPermission(permission,
7893                Binder.getCallingPid(),
7894                UserHandle.getAppId(Binder.getCallingUid()));
7895    }
7896
7897    /**
7898     * This can be called with or without the global lock held.
7899     */
7900    void enforceCallingPermission(String permission, String func) {
7901        if (checkCallingPermission(permission)
7902                == PackageManager.PERMISSION_GRANTED) {
7903            return;
7904        }
7905
7906        String msg = "Permission Denial: " + func + " from pid="
7907                + Binder.getCallingPid()
7908                + ", uid=" + Binder.getCallingUid()
7909                + " requires " + permission;
7910        Slog.w(TAG, msg);
7911        throw new SecurityException(msg);
7912    }
7913
7914    /**
7915     * Determine if UID is holding permissions required to access {@link Uri} in
7916     * the given {@link ProviderInfo}. Final permission checking is always done
7917     * in {@link ContentProvider}.
7918     */
7919    private final boolean checkHoldingPermissionsLocked(
7920            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7921        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7922                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7923        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7924            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7925                    != PERMISSION_GRANTED) {
7926                return false;
7927            }
7928        }
7929        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7930    }
7931
7932    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7933            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7934        if (pi.applicationInfo.uid == uid) {
7935            return true;
7936        } else if (!pi.exported) {
7937            return false;
7938        }
7939
7940        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7941        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7942        try {
7943            // check if target holds top-level <provider> permissions
7944            if (!readMet && pi.readPermission != null && considerUidPermissions
7945                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7946                readMet = true;
7947            }
7948            if (!writeMet && pi.writePermission != null && considerUidPermissions
7949                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7950                writeMet = true;
7951            }
7952
7953            // track if unprotected read/write is allowed; any denied
7954            // <path-permission> below removes this ability
7955            boolean allowDefaultRead = pi.readPermission == null;
7956            boolean allowDefaultWrite = pi.writePermission == null;
7957
7958            // check if target holds any <path-permission> that match uri
7959            final PathPermission[] pps = pi.pathPermissions;
7960            if (pps != null) {
7961                final String path = grantUri.uri.getPath();
7962                int i = pps.length;
7963                while (i > 0 && (!readMet || !writeMet)) {
7964                    i--;
7965                    PathPermission pp = pps[i];
7966                    if (pp.match(path)) {
7967                        if (!readMet) {
7968                            final String pprperm = pp.getReadPermission();
7969                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7970                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7971                                    + ": match=" + pp.match(path)
7972                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7973                            if (pprperm != null) {
7974                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7975                                        == PERMISSION_GRANTED) {
7976                                    readMet = true;
7977                                } else {
7978                                    allowDefaultRead = false;
7979                                }
7980                            }
7981                        }
7982                        if (!writeMet) {
7983                            final String ppwperm = pp.getWritePermission();
7984                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7985                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7986                                    + ": match=" + pp.match(path)
7987                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7988                            if (ppwperm != null) {
7989                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7990                                        == PERMISSION_GRANTED) {
7991                                    writeMet = true;
7992                                } else {
7993                                    allowDefaultWrite = false;
7994                                }
7995                            }
7996                        }
7997                    }
7998                }
7999            }
8000
8001            // grant unprotected <provider> read/write, if not blocked by
8002            // <path-permission> above
8003            if (allowDefaultRead) readMet = true;
8004            if (allowDefaultWrite) writeMet = true;
8005
8006        } catch (RemoteException e) {
8007            return false;
8008        }
8009
8010        return readMet && writeMet;
8011    }
8012
8013    public int getAppStartMode(int uid, String packageName) {
8014        synchronized (this) {
8015            return checkAllowBackgroundLocked(uid, packageName, -1, false);
8016        }
8017    }
8018
8019    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
8020            boolean alwaysRestrict) {
8021        UidRecord uidRec = mActiveUids.get(uid);
8022        if (uidRec == null || alwaysRestrict || uidRec.idle) {
8023            boolean ephemeral;
8024            if (uidRec == null) {
8025                ephemeral = getPackageManagerInternalLocked().isPackageEphemeral(
8026                        UserHandle.getUserId(uid), packageName);
8027            } else {
8028                ephemeral = uidRec.ephemeral;
8029            }
8030
8031            if (ephemeral) {
8032                // We are hard-core about ephemeral apps not running in the background.
8033                return ActivityManager.APP_START_MODE_DISABLED;
8034            } else {
8035                if (callingPid >= 0) {
8036                    ProcessRecord proc;
8037                    synchronized (mPidsSelfLocked) {
8038                        proc = mPidsSelfLocked.get(callingPid);
8039                    }
8040                    if (proc != null && proc.curProcState
8041                            < ActivityManager.PROCESS_STATE_RECEIVER) {
8042                        // Whoever is instigating this is in the foreground, so we will allow it
8043                        // to go through.
8044                        return ActivityManager.APP_START_MODE_NORMAL;
8045                    }
8046                }
8047                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
8048                        packageName) != AppOpsManager.MODE_ALLOWED) {
8049                    return ActivityManager.APP_START_MODE_DELAYED;
8050                }
8051            }
8052        }
8053        return ActivityManager.APP_START_MODE_NORMAL;
8054    }
8055
8056    private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
8057        ProviderInfo pi = null;
8058        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
8059        if (cpr != null) {
8060            pi = cpr.info;
8061        } else {
8062            try {
8063                pi = AppGlobals.getPackageManager().resolveContentProvider(
8064                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
8065                        userHandle);
8066            } catch (RemoteException ex) {
8067            }
8068        }
8069        return pi;
8070    }
8071
8072    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
8073        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8074        if (targetUris != null) {
8075            return targetUris.get(grantUri);
8076        }
8077        return null;
8078    }
8079
8080    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
8081            String targetPkg, int targetUid, GrantUri grantUri) {
8082        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8083        if (targetUris == null) {
8084            targetUris = Maps.newArrayMap();
8085            mGrantedUriPermissions.put(targetUid, targetUris);
8086        }
8087
8088        UriPermission perm = targetUris.get(grantUri);
8089        if (perm == null) {
8090            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
8091            targetUris.put(grantUri, perm);
8092        }
8093
8094        return perm;
8095    }
8096
8097    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
8098            final int modeFlags) {
8099        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
8100        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
8101                : UriPermission.STRENGTH_OWNED;
8102
8103        // Root gets to do everything.
8104        if (uid == 0) {
8105            return true;
8106        }
8107
8108        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8109        if (perms == null) return false;
8110
8111        // First look for exact match
8112        final UriPermission exactPerm = perms.get(grantUri);
8113        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
8114            return true;
8115        }
8116
8117        // No exact match, look for prefixes
8118        final int N = perms.size();
8119        for (int i = 0; i < N; i++) {
8120            final UriPermission perm = perms.valueAt(i);
8121            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
8122                    && perm.getStrength(modeFlags) >= minStrength) {
8123                return true;
8124            }
8125        }
8126
8127        return false;
8128    }
8129
8130    /**
8131     * @param uri This uri must NOT contain an embedded userId.
8132     * @param userId The userId in which the uri is to be resolved.
8133     */
8134    @Override
8135    public int checkUriPermission(Uri uri, int pid, int uid,
8136            final int modeFlags, int userId, IBinder callerToken) {
8137        enforceNotIsolatedCaller("checkUriPermission");
8138
8139        // Another redirected-binder-call permissions check as in
8140        // {@link checkPermissionWithToken}.
8141        Identity tlsIdentity = sCallerIdentity.get();
8142        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8143            uid = tlsIdentity.uid;
8144            pid = tlsIdentity.pid;
8145        }
8146
8147        // Our own process gets to do everything.
8148        if (pid == MY_PID) {
8149            return PackageManager.PERMISSION_GRANTED;
8150        }
8151        synchronized (this) {
8152            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
8153                    ? PackageManager.PERMISSION_GRANTED
8154                    : PackageManager.PERMISSION_DENIED;
8155        }
8156    }
8157
8158    /**
8159     * Check if the targetPkg can be granted permission to access uri by
8160     * the callingUid using the given modeFlags.  Throws a security exception
8161     * if callingUid is not allowed to do this.  Returns the uid of the target
8162     * if the URI permission grant should be performed; returns -1 if it is not
8163     * needed (for example targetPkg already has permission to access the URI).
8164     * If you already know the uid of the target, you can supply it in
8165     * lastTargetUid else set that to -1.
8166     */
8167    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8168            final int modeFlags, int lastTargetUid) {
8169        if (!Intent.isAccessUriMode(modeFlags)) {
8170            return -1;
8171        }
8172
8173        if (targetPkg != null) {
8174            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8175                    "Checking grant " + targetPkg + " permission to " + grantUri);
8176        }
8177
8178        final IPackageManager pm = AppGlobals.getPackageManager();
8179
8180        // If this is not a content: uri, we can't do anything with it.
8181        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8182            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8183                    "Can't grant URI permission for non-content URI: " + grantUri);
8184            return -1;
8185        }
8186
8187        final String authority = grantUri.uri.getAuthority();
8188        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8189                MATCH_DEBUG_TRIAGED_MISSING);
8190        if (pi == null) {
8191            Slog.w(TAG, "No content provider found for permission check: " +
8192                    grantUri.uri.toSafeString());
8193            return -1;
8194        }
8195
8196        int targetUid = lastTargetUid;
8197        if (targetUid < 0 && targetPkg != null) {
8198            try {
8199                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8200                        UserHandle.getUserId(callingUid));
8201                if (targetUid < 0) {
8202                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8203                            "Can't grant URI permission no uid for: " + targetPkg);
8204                    return -1;
8205                }
8206            } catch (RemoteException ex) {
8207                return -1;
8208            }
8209        }
8210
8211        // If we're extending a persistable grant, then we always need to create
8212        // the grant data structure so that take/release APIs work
8213        if ((modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0) {
8214            return targetUid;
8215        }
8216
8217        if (targetUid >= 0) {
8218            // First...  does the target actually need this permission?
8219            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8220                // No need to grant the target this permission.
8221                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8222                        "Target " + targetPkg + " already has full permission to " + grantUri);
8223                return -1;
8224            }
8225        } else {
8226            // First...  there is no target package, so can anyone access it?
8227            boolean allowed = pi.exported;
8228            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8229                if (pi.readPermission != null) {
8230                    allowed = false;
8231                }
8232            }
8233            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8234                if (pi.writePermission != null) {
8235                    allowed = false;
8236                }
8237            }
8238            if (allowed) {
8239                return -1;
8240            }
8241        }
8242
8243        /* There is a special cross user grant if:
8244         * - The target is on another user.
8245         * - Apps on the current user can access the uri without any uid permissions.
8246         * In this case, we grant a uri permission, even if the ContentProvider does not normally
8247         * grant uri permissions.
8248         */
8249        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8250                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8251                modeFlags, false /*without considering the uid permissions*/);
8252
8253        // Second...  is the provider allowing granting of URI permissions?
8254        if (!specialCrossUserGrant) {
8255            if (!pi.grantUriPermissions) {
8256                throw new SecurityException("Provider " + pi.packageName
8257                        + "/" + pi.name
8258                        + " does not allow granting of Uri permissions (uri "
8259                        + grantUri + ")");
8260            }
8261            if (pi.uriPermissionPatterns != null) {
8262                final int N = pi.uriPermissionPatterns.length;
8263                boolean allowed = false;
8264                for (int i=0; i<N; i++) {
8265                    if (pi.uriPermissionPatterns[i] != null
8266                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8267                        allowed = true;
8268                        break;
8269                    }
8270                }
8271                if (!allowed) {
8272                    throw new SecurityException("Provider " + pi.packageName
8273                            + "/" + pi.name
8274                            + " does not allow granting of permission to path of Uri "
8275                            + grantUri);
8276                }
8277            }
8278        }
8279
8280        // Third...  does the caller itself have permission to access
8281        // this uri?
8282        final int callingAppId = UserHandle.getAppId(callingUid);
8283        if ((callingAppId == Process.SYSTEM_UID) || (callingAppId == Process.ROOT_UID)) {
8284            Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
8285                    + " grant to " + grantUri + "; use startActivityAsCaller() instead");
8286            return -1;
8287        } else {
8288            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8289                // Require they hold a strong enough Uri permission
8290                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8291                    throw new SecurityException("Uid " + callingUid
8292                            + " does not have permission to uri " + grantUri);
8293                }
8294            }
8295        }
8296        return targetUid;
8297    }
8298
8299    /**
8300     * @param uri This uri must NOT contain an embedded userId.
8301     * @param userId The userId in which the uri is to be resolved.
8302     */
8303    @Override
8304    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8305            final int modeFlags, int userId) {
8306        enforceNotIsolatedCaller("checkGrantUriPermission");
8307        synchronized(this) {
8308            return checkGrantUriPermissionLocked(callingUid, targetPkg,
8309                    new GrantUri(userId, uri, false), modeFlags, -1);
8310        }
8311    }
8312
8313    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8314            final int modeFlags, UriPermissionOwner owner) {
8315        if (!Intent.isAccessUriMode(modeFlags)) {
8316            return;
8317        }
8318
8319        // So here we are: the caller has the assumed permission
8320        // to the uri, and the target doesn't.  Let's now give this to
8321        // the target.
8322
8323        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8324                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8325
8326        final String authority = grantUri.uri.getAuthority();
8327        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8328                MATCH_DEBUG_TRIAGED_MISSING);
8329        if (pi == null) {
8330            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8331            return;
8332        }
8333
8334        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8335            grantUri.prefix = true;
8336        }
8337        final UriPermission perm = findOrCreateUriPermissionLocked(
8338                pi.packageName, targetPkg, targetUid, grantUri);
8339        perm.grantModes(modeFlags, owner);
8340    }
8341
8342    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8343            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8344        if (targetPkg == null) {
8345            throw new NullPointerException("targetPkg");
8346        }
8347        int targetUid;
8348        final IPackageManager pm = AppGlobals.getPackageManager();
8349        try {
8350            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8351        } catch (RemoteException ex) {
8352            return;
8353        }
8354
8355        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8356                targetUid);
8357        if (targetUid < 0) {
8358            return;
8359        }
8360
8361        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8362                owner);
8363    }
8364
8365    static class NeededUriGrants extends ArrayList<GrantUri> {
8366        final String targetPkg;
8367        final int targetUid;
8368        final int flags;
8369
8370        NeededUriGrants(String targetPkg, int targetUid, int flags) {
8371            this.targetPkg = targetPkg;
8372            this.targetUid = targetUid;
8373            this.flags = flags;
8374        }
8375    }
8376
8377    /**
8378     * Like checkGrantUriPermissionLocked, but takes an Intent.
8379     */
8380    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8381            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8382        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8383                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8384                + " clip=" + (intent != null ? intent.getClipData() : null)
8385                + " from " + intent + "; flags=0x"
8386                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8387
8388        if (targetPkg == null) {
8389            throw new NullPointerException("targetPkg");
8390        }
8391
8392        if (intent == null) {
8393            return null;
8394        }
8395        Uri data = intent.getData();
8396        ClipData clip = intent.getClipData();
8397        if (data == null && clip == null) {
8398            return null;
8399        }
8400        // Default userId for uris in the intent (if they don't specify it themselves)
8401        int contentUserHint = intent.getContentUserHint();
8402        if (contentUserHint == UserHandle.USER_CURRENT) {
8403            contentUserHint = UserHandle.getUserId(callingUid);
8404        }
8405        final IPackageManager pm = AppGlobals.getPackageManager();
8406        int targetUid;
8407        if (needed != null) {
8408            targetUid = needed.targetUid;
8409        } else {
8410            try {
8411                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8412                        targetUserId);
8413            } catch (RemoteException ex) {
8414                return null;
8415            }
8416            if (targetUid < 0) {
8417                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8418                        "Can't grant URI permission no uid for: " + targetPkg
8419                        + " on user " + targetUserId);
8420                return null;
8421            }
8422        }
8423        if (data != null) {
8424            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8425            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8426                    targetUid);
8427            if (targetUid > 0) {
8428                if (needed == null) {
8429                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8430                }
8431                needed.add(grantUri);
8432            }
8433        }
8434        if (clip != null) {
8435            for (int i=0; i<clip.getItemCount(); i++) {
8436                Uri uri = clip.getItemAt(i).getUri();
8437                if (uri != null) {
8438                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8439                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8440                            targetUid);
8441                    if (targetUid > 0) {
8442                        if (needed == null) {
8443                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8444                        }
8445                        needed.add(grantUri);
8446                    }
8447                } else {
8448                    Intent clipIntent = clip.getItemAt(i).getIntent();
8449                    if (clipIntent != null) {
8450                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8451                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8452                        if (newNeeded != null) {
8453                            needed = newNeeded;
8454                        }
8455                    }
8456                }
8457            }
8458        }
8459
8460        return needed;
8461    }
8462
8463    /**
8464     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8465     */
8466    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8467            UriPermissionOwner owner) {
8468        if (needed != null) {
8469            for (int i=0; i<needed.size(); i++) {
8470                GrantUri grantUri = needed.get(i);
8471                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8472                        grantUri, needed.flags, owner);
8473            }
8474        }
8475    }
8476
8477    void grantUriPermissionFromIntentLocked(int callingUid,
8478            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8479        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8480                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8481        if (needed == null) {
8482            return;
8483        }
8484
8485        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8486    }
8487
8488    /**
8489     * @param uri This uri must NOT contain an embedded userId.
8490     * @param userId The userId in which the uri is to be resolved.
8491     */
8492    @Override
8493    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8494            final int modeFlags, int userId) {
8495        enforceNotIsolatedCaller("grantUriPermission");
8496        GrantUri grantUri = new GrantUri(userId, uri, false);
8497        synchronized(this) {
8498            final ProcessRecord r = getRecordForAppLocked(caller);
8499            if (r == null) {
8500                throw new SecurityException("Unable to find app for caller "
8501                        + caller
8502                        + " when granting permission to uri " + grantUri);
8503            }
8504            if (targetPkg == null) {
8505                throw new IllegalArgumentException("null target");
8506            }
8507            if (grantUri == null) {
8508                throw new IllegalArgumentException("null uri");
8509            }
8510
8511            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8512                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8513                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8514                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8515
8516            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8517                    UserHandle.getUserId(r.uid));
8518        }
8519    }
8520
8521    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8522        if (perm.modeFlags == 0) {
8523            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8524                    perm.targetUid);
8525            if (perms != null) {
8526                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8527                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8528
8529                perms.remove(perm.uri);
8530                if (perms.isEmpty()) {
8531                    mGrantedUriPermissions.remove(perm.targetUid);
8532                }
8533            }
8534        }
8535    }
8536
8537    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8538        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8539                "Revoking all granted permissions to " + grantUri);
8540
8541        final IPackageManager pm = AppGlobals.getPackageManager();
8542        final String authority = grantUri.uri.getAuthority();
8543        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8544                MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8545        if (pi == null) {
8546            Slog.w(TAG, "No content provider found for permission revoke: "
8547                    + grantUri.toSafeString());
8548            return;
8549        }
8550
8551        // Does the caller have this permission on the URI?
8552        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8553            // If they don't have direct access to the URI, then revoke any
8554            // ownerless URI permissions that have been granted to them.
8555            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8556            if (perms != null) {
8557                boolean persistChanged = false;
8558                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8559                    final UriPermission perm = it.next();
8560                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8561                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8562                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8563                                "Revoking non-owned " + perm.targetUid
8564                                + " permission to " + perm.uri);
8565                        persistChanged |= perm.revokeModes(
8566                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8567                        if (perm.modeFlags == 0) {
8568                            it.remove();
8569                        }
8570                    }
8571                }
8572                if (perms.isEmpty()) {
8573                    mGrantedUriPermissions.remove(callingUid);
8574                }
8575                if (persistChanged) {
8576                    schedulePersistUriGrants();
8577                }
8578            }
8579            return;
8580        }
8581
8582        boolean persistChanged = false;
8583
8584        // Go through all of the permissions and remove any that match.
8585        int N = mGrantedUriPermissions.size();
8586        for (int i = 0; i < N; i++) {
8587            final int targetUid = mGrantedUriPermissions.keyAt(i);
8588            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8589
8590            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8591                final UriPermission perm = it.next();
8592                if (perm.uri.sourceUserId == grantUri.sourceUserId
8593                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8594                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8595                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8596                    persistChanged |= perm.revokeModes(
8597                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8598                    if (perm.modeFlags == 0) {
8599                        it.remove();
8600                    }
8601                }
8602            }
8603
8604            if (perms.isEmpty()) {
8605                mGrantedUriPermissions.remove(targetUid);
8606                N--;
8607                i--;
8608            }
8609        }
8610
8611        if (persistChanged) {
8612            schedulePersistUriGrants();
8613        }
8614    }
8615
8616    /**
8617     * @param uri This uri must NOT contain an embedded userId.
8618     * @param userId The userId in which the uri is to be resolved.
8619     */
8620    @Override
8621    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8622            int userId) {
8623        enforceNotIsolatedCaller("revokeUriPermission");
8624        synchronized(this) {
8625            final ProcessRecord r = getRecordForAppLocked(caller);
8626            if (r == null) {
8627                throw new SecurityException("Unable to find app for caller "
8628                        + caller
8629                        + " when revoking permission to uri " + uri);
8630            }
8631            if (uri == null) {
8632                Slog.w(TAG, "revokeUriPermission: null uri");
8633                return;
8634            }
8635
8636            if (!Intent.isAccessUriMode(modeFlags)) {
8637                return;
8638            }
8639
8640            final String authority = uri.getAuthority();
8641            final ProviderInfo pi = getProviderInfoLocked(authority, userId,
8642                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8643            if (pi == null) {
8644                Slog.w(TAG, "No content provider found for permission revoke: "
8645                        + uri.toSafeString());
8646                return;
8647            }
8648
8649            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8650        }
8651    }
8652
8653    /**
8654     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8655     * given package.
8656     *
8657     * @param packageName Package name to match, or {@code null} to apply to all
8658     *            packages.
8659     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8660     *            to all users.
8661     * @param persistable If persistable grants should be removed.
8662     */
8663    private void removeUriPermissionsForPackageLocked(
8664            String packageName, int userHandle, boolean persistable) {
8665        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8666            throw new IllegalArgumentException("Must narrow by either package or user");
8667        }
8668
8669        boolean persistChanged = false;
8670
8671        int N = mGrantedUriPermissions.size();
8672        for (int i = 0; i < N; i++) {
8673            final int targetUid = mGrantedUriPermissions.keyAt(i);
8674            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8675
8676            // Only inspect grants matching user
8677            if (userHandle == UserHandle.USER_ALL
8678                    || userHandle == UserHandle.getUserId(targetUid)) {
8679                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8680                    final UriPermission perm = it.next();
8681
8682                    // Only inspect grants matching package
8683                    if (packageName == null || perm.sourcePkg.equals(packageName)
8684                            || perm.targetPkg.equals(packageName)) {
8685                        // Hacky solution as part of fixing a security bug; ignore
8686                        // grants associated with DownloadManager so we don't have
8687                        // to immediately launch it to regrant the permissions
8688                        if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
8689                                && !persistable) continue;
8690
8691                        persistChanged |= perm.revokeModes(persistable
8692                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8693
8694                        // Only remove when no modes remain; any persisted grants
8695                        // will keep this alive.
8696                        if (perm.modeFlags == 0) {
8697                            it.remove();
8698                        }
8699                    }
8700                }
8701
8702                if (perms.isEmpty()) {
8703                    mGrantedUriPermissions.remove(targetUid);
8704                    N--;
8705                    i--;
8706                }
8707            }
8708        }
8709
8710        if (persistChanged) {
8711            schedulePersistUriGrants();
8712        }
8713    }
8714
8715    @Override
8716    public IBinder newUriPermissionOwner(String name) {
8717        enforceNotIsolatedCaller("newUriPermissionOwner");
8718        synchronized(this) {
8719            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8720            return owner.getExternalTokenLocked();
8721        }
8722    }
8723
8724    @Override
8725    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8726        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8727        synchronized(this) {
8728            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8729            if (r == null) {
8730                throw new IllegalArgumentException("Activity does not exist; token="
8731                        + activityToken);
8732            }
8733            return r.getUriPermissionsLocked().getExternalTokenLocked();
8734        }
8735    }
8736    /**
8737     * @param uri This uri must NOT contain an embedded userId.
8738     * @param sourceUserId The userId in which the uri is to be resolved.
8739     * @param targetUserId The userId of the app that receives the grant.
8740     */
8741    @Override
8742    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8743            final int modeFlags, int sourceUserId, int targetUserId) {
8744        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8745                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8746                "grantUriPermissionFromOwner", null);
8747        synchronized(this) {
8748            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8749            if (owner == null) {
8750                throw new IllegalArgumentException("Unknown owner: " + token);
8751            }
8752            if (fromUid != Binder.getCallingUid()) {
8753                if (Binder.getCallingUid() != Process.myUid()) {
8754                    // Only system code can grant URI permissions on behalf
8755                    // of other users.
8756                    throw new SecurityException("nice try");
8757                }
8758            }
8759            if (targetPkg == null) {
8760                throw new IllegalArgumentException("null target");
8761            }
8762            if (uri == null) {
8763                throw new IllegalArgumentException("null uri");
8764            }
8765
8766            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8767                    modeFlags, owner, targetUserId);
8768        }
8769    }
8770
8771    /**
8772     * @param uri This uri must NOT contain an embedded userId.
8773     * @param userId The userId in which the uri is to be resolved.
8774     */
8775    @Override
8776    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8777        synchronized(this) {
8778            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8779            if (owner == null) {
8780                throw new IllegalArgumentException("Unknown owner: " + token);
8781            }
8782
8783            if (uri == null) {
8784                owner.removeUriPermissionsLocked(mode);
8785            } else {
8786                final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
8787                owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
8788            }
8789        }
8790    }
8791
8792    private void schedulePersistUriGrants() {
8793        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8794            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8795                    10 * DateUtils.SECOND_IN_MILLIS);
8796        }
8797    }
8798
8799    private void writeGrantedUriPermissions() {
8800        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8801
8802        // Snapshot permissions so we can persist without lock
8803        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8804        synchronized (this) {
8805            final int size = mGrantedUriPermissions.size();
8806            for (int i = 0; i < size; i++) {
8807                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8808                for (UriPermission perm : perms.values()) {
8809                    if (perm.persistedModeFlags != 0) {
8810                        persist.add(perm.snapshot());
8811                    }
8812                }
8813            }
8814        }
8815
8816        FileOutputStream fos = null;
8817        try {
8818            fos = mGrantFile.startWrite();
8819
8820            XmlSerializer out = new FastXmlSerializer();
8821            out.setOutput(fos, StandardCharsets.UTF_8.name());
8822            out.startDocument(null, true);
8823            out.startTag(null, TAG_URI_GRANTS);
8824            for (UriPermission.Snapshot perm : persist) {
8825                out.startTag(null, TAG_URI_GRANT);
8826                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8827                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8828                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8829                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8830                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8831                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8832                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8833                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8834                out.endTag(null, TAG_URI_GRANT);
8835            }
8836            out.endTag(null, TAG_URI_GRANTS);
8837            out.endDocument();
8838
8839            mGrantFile.finishWrite(fos);
8840        } catch (IOException e) {
8841            if (fos != null) {
8842                mGrantFile.failWrite(fos);
8843            }
8844        }
8845    }
8846
8847    private void readGrantedUriPermissionsLocked() {
8848        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8849
8850        final long now = System.currentTimeMillis();
8851
8852        FileInputStream fis = null;
8853        try {
8854            fis = mGrantFile.openRead();
8855            final XmlPullParser in = Xml.newPullParser();
8856            in.setInput(fis, StandardCharsets.UTF_8.name());
8857
8858            int type;
8859            while ((type = in.next()) != END_DOCUMENT) {
8860                final String tag = in.getName();
8861                if (type == START_TAG) {
8862                    if (TAG_URI_GRANT.equals(tag)) {
8863                        final int sourceUserId;
8864                        final int targetUserId;
8865                        final int userHandle = readIntAttribute(in,
8866                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8867                        if (userHandle != UserHandle.USER_NULL) {
8868                            // For backwards compatibility.
8869                            sourceUserId = userHandle;
8870                            targetUserId = userHandle;
8871                        } else {
8872                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8873                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8874                        }
8875                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8876                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8877                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8878                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8879                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8880                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8881
8882                        // Sanity check that provider still belongs to source package
8883                        // Both direct boot aware and unaware packages are fine as we
8884                        // will do filtering at query time to avoid multiple parsing.
8885                        final ProviderInfo pi = getProviderInfoLocked(
8886                                uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
8887                                        | MATCH_DIRECT_BOOT_UNAWARE);
8888                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8889                            int targetUid = -1;
8890                            try {
8891                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8892                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8893                            } catch (RemoteException e) {
8894                            }
8895                            if (targetUid != -1) {
8896                                final UriPermission perm = findOrCreateUriPermissionLocked(
8897                                        sourcePkg, targetPkg, targetUid,
8898                                        new GrantUri(sourceUserId, uri, prefix));
8899                                perm.initPersistedModes(modeFlags, createdTime);
8900                            }
8901                        } else {
8902                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8903                                    + " but instead found " + pi);
8904                        }
8905                    }
8906                }
8907            }
8908        } catch (FileNotFoundException e) {
8909            // Missing grants is okay
8910        } catch (IOException e) {
8911            Slog.wtf(TAG, "Failed reading Uri grants", e);
8912        } catch (XmlPullParserException e) {
8913            Slog.wtf(TAG, "Failed reading Uri grants", e);
8914        } finally {
8915            IoUtils.closeQuietly(fis);
8916        }
8917    }
8918
8919    /**
8920     * @param uri This uri must NOT contain an embedded userId.
8921     * @param userId The userId in which the uri is to be resolved.
8922     */
8923    @Override
8924    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8925        enforceNotIsolatedCaller("takePersistableUriPermission");
8926
8927        Preconditions.checkFlagsArgument(modeFlags,
8928                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8929
8930        synchronized (this) {
8931            final int callingUid = Binder.getCallingUid();
8932            boolean persistChanged = false;
8933            GrantUri grantUri = new GrantUri(userId, uri, false);
8934
8935            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8936                    new GrantUri(userId, uri, false));
8937            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8938                    new GrantUri(userId, uri, true));
8939
8940            final boolean exactValid = (exactPerm != null)
8941                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8942            final boolean prefixValid = (prefixPerm != null)
8943                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8944
8945            if (!(exactValid || prefixValid)) {
8946                throw new SecurityException("No persistable permission grants found for UID "
8947                        + callingUid + " and Uri " + grantUri.toSafeString());
8948            }
8949
8950            if (exactValid) {
8951                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8952            }
8953            if (prefixValid) {
8954                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8955            }
8956
8957            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8958
8959            if (persistChanged) {
8960                schedulePersistUriGrants();
8961            }
8962        }
8963    }
8964
8965    /**
8966     * @param uri This uri must NOT contain an embedded userId.
8967     * @param userId The userId in which the uri is to be resolved.
8968     */
8969    @Override
8970    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8971        enforceNotIsolatedCaller("releasePersistableUriPermission");
8972
8973        Preconditions.checkFlagsArgument(modeFlags,
8974                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8975
8976        synchronized (this) {
8977            final int callingUid = Binder.getCallingUid();
8978            boolean persistChanged = false;
8979
8980            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8981                    new GrantUri(userId, uri, false));
8982            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8983                    new GrantUri(userId, uri, true));
8984            if (exactPerm == null && prefixPerm == null) {
8985                throw new SecurityException("No permission grants found for UID " + callingUid
8986                        + " and Uri " + uri.toSafeString());
8987            }
8988
8989            if (exactPerm != null) {
8990                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8991                removeUriPermissionIfNeededLocked(exactPerm);
8992            }
8993            if (prefixPerm != null) {
8994                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8995                removeUriPermissionIfNeededLocked(prefixPerm);
8996            }
8997
8998            if (persistChanged) {
8999                schedulePersistUriGrants();
9000            }
9001        }
9002    }
9003
9004    /**
9005     * Prune any older {@link UriPermission} for the given UID until outstanding
9006     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
9007     *
9008     * @return if any mutations occured that require persisting.
9009     */
9010    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
9011        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
9012        if (perms == null) return false;
9013        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
9014
9015        final ArrayList<UriPermission> persisted = Lists.newArrayList();
9016        for (UriPermission perm : perms.values()) {
9017            if (perm.persistedModeFlags != 0) {
9018                persisted.add(perm);
9019            }
9020        }
9021
9022        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
9023        if (trimCount <= 0) return false;
9024
9025        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
9026        for (int i = 0; i < trimCount; i++) {
9027            final UriPermission perm = persisted.get(i);
9028
9029            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9030                    "Trimming grant created at " + perm.persistedCreateTime);
9031
9032            perm.releasePersistableModes(~0);
9033            removeUriPermissionIfNeededLocked(perm);
9034        }
9035
9036        return true;
9037    }
9038
9039    @Override
9040    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
9041            String packageName, boolean incoming) {
9042        enforceNotIsolatedCaller("getPersistedUriPermissions");
9043        Preconditions.checkNotNull(packageName, "packageName");
9044
9045        final int callingUid = Binder.getCallingUid();
9046        final int callingUserId = UserHandle.getUserId(callingUid);
9047        final IPackageManager pm = AppGlobals.getPackageManager();
9048        try {
9049            final int packageUid = pm.getPackageUid(packageName,
9050                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
9051            if (packageUid != callingUid) {
9052                throw new SecurityException(
9053                        "Package " + packageName + " does not belong to calling UID " + callingUid);
9054            }
9055        } catch (RemoteException e) {
9056            throw new SecurityException("Failed to verify package name ownership");
9057        }
9058
9059        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9060        synchronized (this) {
9061            if (incoming) {
9062                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9063                        callingUid);
9064                if (perms == null) {
9065                    Slog.w(TAG, "No permission grants found for " + packageName);
9066                } else {
9067                    for (UriPermission perm : perms.values()) {
9068                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
9069                            result.add(perm.buildPersistedPublicApiObject());
9070                        }
9071                    }
9072                }
9073            } else {
9074                final int size = mGrantedUriPermissions.size();
9075                for (int i = 0; i < size; i++) {
9076                    final ArrayMap<GrantUri, UriPermission> perms =
9077                            mGrantedUriPermissions.valueAt(i);
9078                    for (UriPermission perm : perms.values()) {
9079                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
9080                            result.add(perm.buildPersistedPublicApiObject());
9081                        }
9082                    }
9083                }
9084            }
9085        }
9086        return new ParceledListSlice<android.content.UriPermission>(result);
9087    }
9088
9089    @Override
9090    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
9091            String packageName, int userId) {
9092        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
9093                "getGrantedUriPermissions");
9094
9095        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9096        synchronized (this) {
9097            final int size = mGrantedUriPermissions.size();
9098            for (int i = 0; i < size; i++) {
9099                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9100                for (UriPermission perm : perms.values()) {
9101                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
9102                            && perm.persistedModeFlags != 0) {
9103                        result.add(perm.buildPersistedPublicApiObject());
9104                    }
9105                }
9106            }
9107        }
9108        return new ParceledListSlice<android.content.UriPermission>(result);
9109    }
9110
9111    @Override
9112    public void clearGrantedUriPermissions(String packageName, int userId) {
9113        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
9114                "clearGrantedUriPermissions");
9115        removeUriPermissionsForPackageLocked(packageName, userId, true);
9116    }
9117
9118    @Override
9119    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
9120        synchronized (this) {
9121            ProcessRecord app =
9122                who != null ? getRecordForAppLocked(who) : null;
9123            if (app == null) return;
9124
9125            Message msg = Message.obtain();
9126            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
9127            msg.obj = app;
9128            msg.arg1 = waiting ? 1 : 0;
9129            mUiHandler.sendMessage(msg);
9130        }
9131    }
9132
9133    @Override
9134    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
9135        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
9136        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
9137        outInfo.availMem = Process.getFreeMemory();
9138        outInfo.totalMem = Process.getTotalMemory();
9139        outInfo.threshold = homeAppMem;
9140        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
9141        outInfo.hiddenAppThreshold = cachedAppMem;
9142        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
9143                ProcessList.SERVICE_ADJ);
9144        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
9145                ProcessList.VISIBLE_APP_ADJ);
9146        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
9147                ProcessList.FOREGROUND_APP_ADJ);
9148    }
9149
9150    // =========================================================
9151    // TASK MANAGEMENT
9152    // =========================================================
9153
9154    @Override
9155    public List<IBinder> getAppTasks(String callingPackage) {
9156        int callingUid = Binder.getCallingUid();
9157        long ident = Binder.clearCallingIdentity();
9158
9159        synchronized(this) {
9160            ArrayList<IBinder> list = new ArrayList<IBinder>();
9161            try {
9162                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
9163
9164                final int N = mRecentTasks.size();
9165                for (int i = 0; i < N; i++) {
9166                    TaskRecord tr = mRecentTasks.get(i);
9167                    // Skip tasks that do not match the caller.  We don't need to verify
9168                    // callingPackage, because we are also limiting to callingUid and know
9169                    // that will limit to the correct security sandbox.
9170                    if (tr.effectiveUid != callingUid) {
9171                        continue;
9172                    }
9173                    Intent intent = tr.getBaseIntent();
9174                    if (intent == null ||
9175                            !callingPackage.equals(intent.getComponent().getPackageName())) {
9176                        continue;
9177                    }
9178                    ActivityManager.RecentTaskInfo taskInfo =
9179                            createRecentTaskInfoFromTaskRecord(tr);
9180                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
9181                    list.add(taskImpl.asBinder());
9182                }
9183            } finally {
9184                Binder.restoreCallingIdentity(ident);
9185            }
9186            return list;
9187        }
9188    }
9189
9190    @Override
9191    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9192        final int callingUid = Binder.getCallingUid();
9193        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9194
9195        synchronized(this) {
9196            if (DEBUG_ALL) Slog.v(
9197                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9198
9199            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9200                    callingUid);
9201
9202            // TODO: Improve with MRU list from all ActivityStacks.
9203            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9204        }
9205
9206        return list;
9207    }
9208
9209    /**
9210     * Creates a new RecentTaskInfo from a TaskRecord.
9211     */
9212    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9213        // Update the task description to reflect any changes in the task stack
9214        tr.updateTaskDescription();
9215
9216        // Compose the recent task info
9217        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9218        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9219        rti.persistentId = tr.taskId;
9220        rti.baseIntent = new Intent(tr.getBaseIntent());
9221        rti.origActivity = tr.origActivity;
9222        rti.realActivity = tr.realActivity;
9223        rti.description = tr.lastDescription;
9224        rti.stackId = tr.getStackId();
9225        rti.userId = tr.userId;
9226        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9227        rti.firstActiveTime = tr.firstActiveTime;
9228        rti.lastActiveTime = tr.lastActiveTime;
9229        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9230        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9231        rti.numActivities = 0;
9232        if (tr.mBounds != null) {
9233            rti.bounds = new Rect(tr.mBounds);
9234        }
9235        rti.isDockable = tr.canGoInDockedStack();
9236        rti.resizeMode = tr.mResizeMode;
9237
9238        ActivityRecord base = null;
9239        ActivityRecord top = null;
9240        ActivityRecord tmp;
9241
9242        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9243            tmp = tr.mActivities.get(i);
9244            if (tmp.finishing) {
9245                continue;
9246            }
9247            base = tmp;
9248            if (top == null || (top.state == ActivityState.INITIALIZING)) {
9249                top = base;
9250            }
9251            rti.numActivities++;
9252        }
9253
9254        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9255        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9256
9257        return rti;
9258    }
9259
9260    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9261        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9262                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9263        if (!allowed) {
9264            if (checkPermission(android.Manifest.permission.GET_TASKS,
9265                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9266                // Temporary compatibility: some existing apps on the system image may
9267                // still be requesting the old permission and not switched to the new
9268                // one; if so, we'll still allow them full access.  This means we need
9269                // to see if they are holding the old permission and are a system app.
9270                try {
9271                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9272                        allowed = true;
9273                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9274                                + " is using old GET_TASKS but privileged; allowing");
9275                    }
9276                } catch (RemoteException e) {
9277                }
9278            }
9279        }
9280        if (!allowed) {
9281            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9282                    + " does not hold REAL_GET_TASKS; limiting output");
9283        }
9284        return allowed;
9285    }
9286
9287    @Override
9288    public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9289            int userId) {
9290        final int callingUid = Binder.getCallingUid();
9291        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9292                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9293
9294        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9295        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9296        synchronized (this) {
9297            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9298                    callingUid);
9299            final boolean detailed = checkCallingPermission(
9300                    android.Manifest.permission.GET_DETAILED_TASKS)
9301                    == PackageManager.PERMISSION_GRANTED;
9302
9303            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9304                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9305                return ParceledListSlice.emptyList();
9306            }
9307            mRecentTasks.loadUserRecentsLocked(userId);
9308
9309            final int recentsCount = mRecentTasks.size();
9310            ArrayList<ActivityManager.RecentTaskInfo> res =
9311                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9312
9313            final Set<Integer> includedUsers;
9314            if (includeProfiles) {
9315                includedUsers = mUserController.getProfileIds(userId);
9316            } else {
9317                includedUsers = new HashSet<>();
9318            }
9319            includedUsers.add(Integer.valueOf(userId));
9320
9321            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9322                TaskRecord tr = mRecentTasks.get(i);
9323                // Only add calling user or related users recent tasks
9324                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9325                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9326                    continue;
9327                }
9328
9329                if (tr.realActivitySuspended) {
9330                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9331                    continue;
9332                }
9333
9334                // Return the entry if desired by the caller.  We always return
9335                // the first entry, because callers always expect this to be the
9336                // foreground app.  We may filter others if the caller has
9337                // not supplied RECENT_WITH_EXCLUDED and there is some reason
9338                // we should exclude the entry.
9339
9340                if (i == 0
9341                        || withExcluded
9342                        || (tr.intent == null)
9343                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9344                                == 0)) {
9345                    if (!allowed) {
9346                        // If the caller doesn't have the GET_TASKS permission, then only
9347                        // allow them to see a small subset of tasks -- their own and home.
9348                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9349                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9350                            continue;
9351                        }
9352                    }
9353                    final ActivityStack stack = tr.getStack();
9354                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_AND_RECENTS_STACK_TASKS) != 0) {
9355                        if (stack != null && stack.isHomeOrRecentsStack()) {
9356                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9357                                    "Skipping, home or recents stack task: " + tr);
9358                            continue;
9359                        }
9360                    }
9361                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9362                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9363                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9364                                    "Skipping, top task in docked stack: " + tr);
9365                            continue;
9366                        }
9367                    }
9368                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9369                        if (stack != null && stack.isPinnedStack()) {
9370                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9371                                    "Skipping, pinned stack task: " + tr);
9372                            continue;
9373                        }
9374                    }
9375                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9376                        // Don't include auto remove tasks that are finished or finishing.
9377                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9378                                "Skipping, auto-remove without activity: " + tr);
9379                        continue;
9380                    }
9381                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9382                            && !tr.isAvailable) {
9383                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9384                                "Skipping, unavail real act: " + tr);
9385                        continue;
9386                    }
9387
9388                    if (!tr.mUserSetupComplete) {
9389                        // Don't include task launched while user is not done setting-up.
9390                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9391                                "Skipping, user setup not complete: " + tr);
9392                        continue;
9393                    }
9394
9395                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9396                    if (!detailed) {
9397                        rti.baseIntent.replaceExtras((Bundle)null);
9398                    }
9399
9400                    res.add(rti);
9401                    maxNum--;
9402                }
9403            }
9404            return new ParceledListSlice<>(res);
9405        }
9406    }
9407
9408    @Override
9409    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9410        synchronized (this) {
9411            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9412                    "getTaskThumbnail()");
9413            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9414                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9415            if (tr != null) {
9416                return tr.getTaskThumbnailLocked();
9417            }
9418        }
9419        return null;
9420    }
9421
9422    @Override
9423    public int addAppTask(IBinder activityToken, Intent intent,
9424            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9425        final int callingUid = Binder.getCallingUid();
9426        final long callingIdent = Binder.clearCallingIdentity();
9427
9428        try {
9429            synchronized (this) {
9430                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9431                if (r == null) {
9432                    throw new IllegalArgumentException("Activity does not exist; token="
9433                            + activityToken);
9434                }
9435                ComponentName comp = intent.getComponent();
9436                if (comp == null) {
9437                    throw new IllegalArgumentException("Intent " + intent
9438                            + " must specify explicit component");
9439                }
9440                if (thumbnail.getWidth() != mThumbnailWidth
9441                        || thumbnail.getHeight() != mThumbnailHeight) {
9442                    throw new IllegalArgumentException("Bad thumbnail size: got "
9443                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9444                            + mThumbnailWidth + "x" + mThumbnailHeight);
9445                }
9446                if (intent.getSelector() != null) {
9447                    intent.setSelector(null);
9448                }
9449                if (intent.getSourceBounds() != null) {
9450                    intent.setSourceBounds(null);
9451                }
9452                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9453                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9454                        // The caller has added this as an auto-remove task...  that makes no
9455                        // sense, so turn off auto-remove.
9456                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9457                    }
9458                }
9459                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9460                    mLastAddedTaskActivity = null;
9461                }
9462                ActivityInfo ainfo = mLastAddedTaskActivity;
9463                if (ainfo == null) {
9464                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9465                            comp, 0, UserHandle.getUserId(callingUid));
9466                    if (ainfo.applicationInfo.uid != callingUid) {
9467                        throw new SecurityException(
9468                                "Can't add task for another application: target uid="
9469                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9470                    }
9471                }
9472
9473                TaskRecord task = new TaskRecord(this,
9474                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9475                        ainfo, intent, description, new TaskThumbnailInfo());
9476
9477                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9478                if (trimIdx >= 0) {
9479                    // If this would have caused a trim, then we'll abort because that
9480                    // means it would be added at the end of the list but then just removed.
9481                    return INVALID_TASK_ID;
9482                }
9483
9484                final int N = mRecentTasks.size();
9485                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9486                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9487                    tr.removedFromRecents();
9488                }
9489
9490                task.inRecents = true;
9491                mRecentTasks.add(task);
9492                r.getStack().addTask(task, false, "addAppTask");
9493
9494                task.setLastThumbnailLocked(thumbnail);
9495                task.freeLastThumbnail();
9496                return task.taskId;
9497            }
9498        } finally {
9499            Binder.restoreCallingIdentity(callingIdent);
9500        }
9501    }
9502
9503    @Override
9504    public Point getAppTaskThumbnailSize() {
9505        synchronized (this) {
9506            return new Point(mThumbnailWidth,  mThumbnailHeight);
9507        }
9508    }
9509
9510    @Override
9511    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9512        synchronized (this) {
9513            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9514            if (r != null) {
9515                r.setTaskDescription(td);
9516                r.task.updateTaskDescription();
9517                mTaskChangeNotificationController.notifyTaskDescriptionChanged(r.task.taskId, td);
9518            }
9519        }
9520    }
9521
9522    @Override
9523    public void setTaskResizeable(int taskId, int resizeableMode) {
9524        synchronized (this) {
9525            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9526                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9527            if (task == null) {
9528                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9529                return;
9530            }
9531            task.setResizeMode(resizeableMode);
9532        }
9533    }
9534
9535    @Override
9536    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9537        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9538        long ident = Binder.clearCallingIdentity();
9539        try {
9540            synchronized (this) {
9541                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9542                if (task == null) {
9543                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9544                    return;
9545                }
9546                // Place the task in the right stack if it isn't there already based on
9547                // the requested bounds.
9548                // The stack transition logic is:
9549                // - a null bounds on a freeform task moves that task to fullscreen
9550                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9551                //   that task to freeform
9552                // - otherwise the task is not moved
9553                int stackId = task.getStackId();
9554                if (!StackId.isTaskResizeAllowed(stackId)) {
9555                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9556                }
9557                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9558                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9559                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9560                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9561                }
9562                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9563                if (stackId != task.getStackId()) {
9564                    mStackSupervisor.moveTaskToStackUncheckedLocked(task, stackId, ON_TOP,
9565                            !FORCE_FOCUS, "resizeTask", true /* allowStackOnTop */);
9566                    preserveWindow = false;
9567                }
9568
9569                task.resize(bounds, resizeMode, preserveWindow, false /* deferResume */);
9570            }
9571        } finally {
9572            Binder.restoreCallingIdentity(ident);
9573        }
9574    }
9575
9576    @Override
9577    public Rect getTaskBounds(int taskId) {
9578        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9579        long ident = Binder.clearCallingIdentity();
9580        Rect rect = new Rect();
9581        try {
9582            synchronized (this) {
9583                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9584                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9585                if (task == null) {
9586                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9587                    return rect;
9588                }
9589                if (task.getStack() != null) {
9590                    // Return the bounds from window manager since it will be adjusted for various
9591                    // things like the presense of a docked stack for tasks that aren't resizeable.
9592                    task.getWindowContainerBounds(rect);
9593                } else {
9594                    // Task isn't in window manager yet since it isn't associated with a stack.
9595                    // Return the persist value from activity manager
9596                    if (task.mBounds != null) {
9597                        rect.set(task.mBounds);
9598                    } else if (task.mLastNonFullscreenBounds != null) {
9599                        rect.set(task.mLastNonFullscreenBounds);
9600                    }
9601                }
9602            }
9603        } finally {
9604            Binder.restoreCallingIdentity(ident);
9605        }
9606        return rect;
9607    }
9608
9609    @Override
9610    public void cancelTaskWindowTransition(int taskId) {
9611        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskWindowTransition()");
9612        final long ident = Binder.clearCallingIdentity();
9613        try {
9614            synchronized (this) {
9615                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9616                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9617                if (task == null) {
9618                    Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
9619                    return;
9620                }
9621                task.cancelWindowTransition();
9622            }
9623        } finally {
9624            Binder.restoreCallingIdentity(ident);
9625        }
9626    }
9627
9628    @Override
9629    public void cancelTaskThumbnailTransition(int taskId) {
9630        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskThumbnailTransition()");
9631        final long ident = Binder.clearCallingIdentity();
9632        try {
9633            synchronized (this) {
9634                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9635                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9636                if (task == null) {
9637                    Slog.w(TAG, "cancelTaskThumbnailTransition: taskId=" + taskId + " not found");
9638                    return;
9639                }
9640                task.cancelThumbnailTransition();
9641            }
9642        } finally {
9643            Binder.restoreCallingIdentity(ident);
9644        }
9645    }
9646
9647    @Override
9648    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9649        if (userId != UserHandle.getCallingUserId()) {
9650            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9651                    "getTaskDescriptionIcon");
9652        }
9653        final File passedIconFile = new File(filePath);
9654        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9655                passedIconFile.getName());
9656        if (!legitIconFile.getPath().equals(filePath)
9657                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9658            throw new IllegalArgumentException("Bad file path: " + filePath
9659                    + " passed for userId " + userId);
9660        }
9661        return mRecentTasks.getTaskDescriptionIcon(filePath);
9662    }
9663
9664    @Override
9665    public void startInPlaceAnimationOnFrontMostApplication(Bundle opts)
9666            throws RemoteException {
9667        final ActivityOptions activityOptions = ActivityOptions.fromBundle(opts);
9668        if (activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9669                activityOptions.getCustomInPlaceResId() == 0) {
9670            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9671                    "with valid animation");
9672        }
9673        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9674        mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
9675                activityOptions.getCustomInPlaceResId());
9676        mWindowManager.executeAppTransition();
9677    }
9678
9679    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9680        // Remove all tasks with activities in the specified package from the list of recent tasks
9681        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9682            TaskRecord tr = mRecentTasks.get(i);
9683            if (tr.userId != userId) continue;
9684
9685            ComponentName cn = tr.intent.getComponent();
9686            if (cn != null && cn.getPackageName().equals(packageName)) {
9687                // If the package name matches, remove the task.
9688                mStackSupervisor.removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9689            }
9690        }
9691    }
9692
9693    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9694            int userId) {
9695
9696        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9697            TaskRecord tr = mRecentTasks.get(i);
9698            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9699                continue;
9700            }
9701
9702            ComponentName cn = tr.intent.getComponent();
9703            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9704                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9705            if (sameComponent) {
9706                mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9707            }
9708        }
9709    }
9710
9711    @Override
9712    public void removeStack(int stackId) {
9713        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9714        if (StackId.isHomeOrRecentsStack(stackId)) {
9715            throw new IllegalArgumentException("Removing home or recents stack is not allowed.");
9716        }
9717
9718        synchronized (this) {
9719            final long ident = Binder.clearCallingIdentity();
9720            try {
9721                mStackSupervisor.removeStackLocked(stackId);
9722            } finally {
9723                Binder.restoreCallingIdentity(ident);
9724            }
9725        }
9726    }
9727
9728    @Override
9729    public void moveStackToDisplay(int stackId, int displayId) {
9730        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveStackToDisplay()");
9731
9732        synchronized (this) {
9733            final long ident = Binder.clearCallingIdentity();
9734            try {
9735                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
9736                        + " to displayId=" + displayId);
9737                mStackSupervisor.moveStackToDisplayLocked(stackId, displayId);
9738            } finally {
9739                Binder.restoreCallingIdentity(ident);
9740            }
9741        }
9742    }
9743
9744    @Override
9745    public boolean removeTask(int taskId) {
9746        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9747        synchronized (this) {
9748            final long ident = Binder.clearCallingIdentity();
9749            try {
9750                return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9751            } finally {
9752                Binder.restoreCallingIdentity(ident);
9753            }
9754        }
9755    }
9756
9757    /**
9758     * TODO: Add mController hook
9759     */
9760    @Override
9761    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9762        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9763
9764        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9765        synchronized(this) {
9766            moveTaskToFrontLocked(taskId, flags, bOptions);
9767        }
9768    }
9769
9770    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9771        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9772
9773        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9774                Binder.getCallingUid(), -1, -1, "Task to front")) {
9775            ActivityOptions.abort(options);
9776            return;
9777        }
9778        final long origId = Binder.clearCallingIdentity();
9779        try {
9780            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9781            if (task == null) {
9782                Slog.d(TAG, "Could not find task for id: "+ taskId);
9783                return;
9784            }
9785            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9786                mStackSupervisor.showLockTaskToast();
9787                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9788                return;
9789            }
9790            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9791            if (prev != null && prev.isRecentsActivity()) {
9792                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9793            }
9794            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9795                    false /* forceNonResizable */);
9796        } finally {
9797            Binder.restoreCallingIdentity(origId);
9798        }
9799        ActivityOptions.abort(options);
9800    }
9801
9802    /**
9803     * Moves an activity, and all of the other activities within the same task, to the bottom
9804     * of the history stack.  The activity's order within the task is unchanged.
9805     *
9806     * @param token A reference to the activity we wish to move
9807     * @param nonRoot If false then this only works if the activity is the root
9808     *                of a task; if true it will work for any activity in a task.
9809     * @return Returns true if the move completed, false if not.
9810     */
9811    @Override
9812    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9813        enforceNotIsolatedCaller("moveActivityTaskToBack");
9814        synchronized(this) {
9815            final long origId = Binder.clearCallingIdentity();
9816            try {
9817                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9818                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9819                if (task != null) {
9820                    if (mStackSupervisor.isLockedTask(task)) {
9821                        mStackSupervisor.showLockTaskToast();
9822                        return false;
9823                    }
9824                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9825                }
9826            } finally {
9827                Binder.restoreCallingIdentity(origId);
9828            }
9829        }
9830        return false;
9831    }
9832
9833    @Override
9834    public void moveTaskBackwards(int task) {
9835        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9836                "moveTaskBackwards()");
9837
9838        synchronized(this) {
9839            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9840                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9841                return;
9842            }
9843            final long origId = Binder.clearCallingIdentity();
9844            moveTaskBackwardsLocked(task);
9845            Binder.restoreCallingIdentity(origId);
9846        }
9847    }
9848
9849    private final void moveTaskBackwardsLocked(int task) {
9850        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9851    }
9852
9853    @Override
9854    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9855            IActivityContainerCallback callback) throws RemoteException {
9856        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9857        synchronized (this) {
9858            if (parentActivityToken == null) {
9859                throw new IllegalArgumentException("parent token must not be null");
9860            }
9861            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9862            if (r == null) {
9863                return null;
9864            }
9865            if (callback == null) {
9866                throw new IllegalArgumentException("callback must not be null");
9867            }
9868            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9869        }
9870    }
9871
9872    @Override
9873    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9874        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9875        synchronized (this) {
9876            final int stackId = mStackSupervisor.getNextStackId();
9877            final ActivityStack stack =
9878                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9879            if (stack == null) {
9880                return null;
9881            }
9882            return stack.mActivityContainer;
9883        }
9884    }
9885
9886    @Override
9887    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9888        synchronized (this) {
9889            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9890            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9891                return stack.mActivityContainer.getDisplayId();
9892            }
9893            return DEFAULT_DISPLAY;
9894        }
9895    }
9896
9897    @Override
9898    public int getActivityStackId(IBinder token) throws RemoteException {
9899        synchronized (this) {
9900            ActivityStack stack = ActivityRecord.getStackLocked(token);
9901            if (stack == null) {
9902                return INVALID_STACK_ID;
9903            }
9904            return stack.mStackId;
9905        }
9906    }
9907
9908    @Override
9909    public void exitFreeformMode(IBinder token) throws RemoteException {
9910        synchronized (this) {
9911            long ident = Binder.clearCallingIdentity();
9912            try {
9913                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9914                if (r == null) {
9915                    throw new IllegalArgumentException(
9916                            "exitFreeformMode: No activity record matching token=" + token);
9917                }
9918                final ActivityStack stack = r.getStackLocked(token);
9919                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9920                    throw new IllegalStateException(
9921                            "exitFreeformMode: You can only go fullscreen from freeform.");
9922                }
9923                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9924                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9925                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9926            } finally {
9927                Binder.restoreCallingIdentity(ident);
9928            }
9929        }
9930    }
9931
9932    @Override
9933    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9934        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9935        if (StackId.isHomeOrRecentsStack(stackId)) {
9936            throw new IllegalArgumentException(
9937                    "moveTaskToStack: Attempt to move task " + taskId + " to stack " + stackId);
9938        }
9939        synchronized (this) {
9940            long ident = Binder.clearCallingIdentity();
9941            try {
9942                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9943                        + " to stackId=" + stackId + " toTop=" + toTop);
9944                if (stackId == DOCKED_STACK_ID) {
9945                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9946                            null /* initialBounds */);
9947                }
9948                boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9949                        !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9950                if (result && stackId == DOCKED_STACK_ID) {
9951                    // If task moved to docked stack - show recents if needed.
9952                    mWindowManager.showRecentApps(false /* fromHome */);
9953                }
9954            } finally {
9955                Binder.restoreCallingIdentity(ident);
9956            }
9957        }
9958    }
9959
9960    @Override
9961    public void swapDockedAndFullscreenStack() throws RemoteException {
9962        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9963        synchronized (this) {
9964            long ident = Binder.clearCallingIdentity();
9965            try {
9966                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9967                        FULLSCREEN_WORKSPACE_STACK_ID);
9968                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9969                        : null;
9970                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9971                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9972                        : null;
9973                if (topTask == null || tasks == null || tasks.size() == 0) {
9974                    Slog.w(TAG,
9975                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
9976                    return;
9977                }
9978
9979                // TODO: App transition
9980                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9981
9982                // Defer the resume so resume/pausing while moving stacks is dangerous.
9983                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9984                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9985                        ANIMATE, true /* deferResume */, true /* allowStackOnTop */);
9986                final int size = tasks.size();
9987                for (int i = 0; i < size; i++) {
9988                    final int id = tasks.get(i).taskId;
9989                    if (id == topTask.taskId) {
9990                        continue;
9991                    }
9992                    mStackSupervisor.moveTaskToStackLocked(id,
9993                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9994                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */,
9995                            true /* allowStackOnTop */);
9996                }
9997
9998                // Because we deferred the resume, to avoid conflicts with stack switches while
9999                // resuming, we need to do it after all the tasks are moved.
10000                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10001                mStackSupervisor.resumeFocusedStackTopActivityLocked();
10002
10003                mWindowManager.executeAppTransition();
10004            } finally {
10005                Binder.restoreCallingIdentity(ident);
10006            }
10007        }
10008    }
10009
10010    /**
10011     * Moves the input task to the docked stack.
10012     *
10013     * @param taskId Id of task to move.
10014     * @param createMode The mode the docked stack should be created in if it doesn't exist
10015     *                   already. See
10016     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
10017     *                   and
10018     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
10019     * @param toTop If the task and stack should be moved to the top.
10020     * @param animate Whether we should play an animation for the moving the task
10021     * @param initialBounds If the docked stack gets created, it will use these bounds for the
10022     *                      docked stack. Pass {@code null} to use default bounds.
10023     */
10024    @Override
10025    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
10026            Rect initialBounds, boolean moveHomeStackFront) {
10027        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
10028        synchronized (this) {
10029            long ident = Binder.clearCallingIdentity();
10030            try {
10031                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
10032                        + " to createMode=" + createMode + " toTop=" + toTop);
10033                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
10034                final boolean moved = mStackSupervisor.moveTaskToStackLocked(
10035                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
10036                        animate, DEFER_RESUME, true /* allowStackOnTop */);
10037                if (moved) {
10038                    if (moveHomeStackFront) {
10039                        mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
10040                    }
10041                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10042                }
10043                return moved;
10044            } finally {
10045                Binder.restoreCallingIdentity(ident);
10046            }
10047        }
10048    }
10049
10050    /**
10051     * Moves the top activity in the input stackId to the pinned stack.
10052     *
10053     * @param stackId Id of stack to move the top activity to pinned stack.
10054     * @param bounds Bounds to use for pinned stack.
10055     *
10056     * @return True if the top activity of the input stack was successfully moved to the pinned
10057     *          stack.
10058     */
10059    @Override
10060    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
10061        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
10062        synchronized (this) {
10063            if (!mSupportsPictureInPicture) {
10064                throw new IllegalStateException("moveTopActivityToPinnedStack:"
10065                        + "Device doesn't support picture-in-pciture mode");
10066            }
10067
10068            long ident = Binder.clearCallingIdentity();
10069            try {
10070                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
10071            } finally {
10072                Binder.restoreCallingIdentity(ident);
10073            }
10074        }
10075    }
10076
10077    @Override
10078    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
10079            boolean preserveWindows, boolean animate, int animationDuration) {
10080        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
10081        long ident = Binder.clearCallingIdentity();
10082        try {
10083            synchronized (this) {
10084                if (animate) {
10085                    if (stackId == PINNED_STACK_ID) {
10086                        mWindowManager.animateResizePinnedStack(bounds, animationDuration);
10087                    } else {
10088                        throw new IllegalArgumentException("Stack: " + stackId
10089                                + " doesn't support animated resize.");
10090                    }
10091                } else {
10092                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
10093                            null /* tempTaskInsetBounds */, preserveWindows,
10094                            allowResizeInDockedMode, !DEFER_RESUME);
10095                }
10096            }
10097        } finally {
10098            Binder.restoreCallingIdentity(ident);
10099        }
10100    }
10101
10102    @Override
10103    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10104            Rect tempDockedTaskInsetBounds,
10105            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10106        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10107                "resizeDockedStack()");
10108        long ident = Binder.clearCallingIdentity();
10109        try {
10110            synchronized (this) {
10111                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10112                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10113                        PRESERVE_WINDOWS);
10114            }
10115        } finally {
10116            Binder.restoreCallingIdentity(ident);
10117        }
10118    }
10119
10120    @Override
10121    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10122        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10123                "resizePinnedStack()");
10124        final long ident = Binder.clearCallingIdentity();
10125        try {
10126            synchronized (this) {
10127                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10128            }
10129        } finally {
10130            Binder.restoreCallingIdentity(ident);
10131        }
10132    }
10133
10134    /**
10135     * Try to place task to provided position. The final position might be different depending on
10136     * current user and stacks state. The task will be moved to target stack if it's currently in
10137     * different stack.
10138     */
10139    @Override
10140    public void positionTaskInStack(int taskId, int stackId, int position) {
10141        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10142        if (StackId.isHomeOrRecentsStack(stackId)) {
10143            throw new IllegalArgumentException(
10144                    "positionTaskInStack: Attempt to change the position of task "
10145                    + taskId + " in/to home/recents stack");
10146        }
10147        synchronized (this) {
10148            long ident = Binder.clearCallingIdentity();
10149            try {
10150                if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
10151                        + taskId + " in stackId=" + stackId + " at position=" + position);
10152                final ActivityStack stack = mStackSupervisor.getStack(stackId, CREATE_IF_NEEDED,
10153                        !ON_TOP);
10154
10155                stack.positionChildAt(taskId, position);
10156            } finally {
10157                Binder.restoreCallingIdentity(ident);
10158            }
10159        }
10160    }
10161
10162    @Override
10163    public List<StackInfo> getAllStackInfos() {
10164        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10165        long ident = Binder.clearCallingIdentity();
10166        try {
10167            synchronized (this) {
10168                return mStackSupervisor.getAllStackInfosLocked();
10169            }
10170        } finally {
10171            Binder.restoreCallingIdentity(ident);
10172        }
10173    }
10174
10175    @Override
10176    public StackInfo getStackInfo(int stackId) {
10177        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10178        long ident = Binder.clearCallingIdentity();
10179        try {
10180            synchronized (this) {
10181                return mStackSupervisor.getStackInfoLocked(stackId);
10182            }
10183        } finally {
10184            Binder.restoreCallingIdentity(ident);
10185        }
10186    }
10187
10188    @Override
10189    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10190        synchronized(this) {
10191            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10192        }
10193    }
10194
10195    @Override
10196    public void updateDeviceOwner(String packageName) {
10197        final int callingUid = Binder.getCallingUid();
10198        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10199            throw new SecurityException("updateDeviceOwner called from non-system process");
10200        }
10201        synchronized (this) {
10202            mDeviceOwnerName = packageName;
10203        }
10204    }
10205
10206    @Override
10207    public void updateLockTaskPackages(int userId, String[] packages) {
10208        final int callingUid = Binder.getCallingUid();
10209        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10210            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10211                    "updateLockTaskPackages()");
10212        }
10213        synchronized (this) {
10214            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10215                    Arrays.toString(packages));
10216            mLockTaskPackages.put(userId, packages);
10217            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10218        }
10219    }
10220
10221
10222    void startLockTaskModeLocked(TaskRecord task) {
10223        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10224        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10225            return;
10226        }
10227
10228        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10229        // is initiated by system after the pinning request was shown and locked mode is initiated
10230        // by an authorized app directly
10231        final int callingUid = Binder.getCallingUid();
10232        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10233        long ident = Binder.clearCallingIdentity();
10234        try {
10235            if (!isSystemInitiated) {
10236                task.mLockTaskUid = callingUid;
10237                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10238                    // startLockTask() called by app and task mode is lockTaskModeDefault.
10239                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10240                    StatusBarManagerInternal statusBarManager =
10241                            LocalServices.getService(StatusBarManagerInternal.class);
10242                    if (statusBarManager != null) {
10243                        statusBarManager.showScreenPinningRequest(task.taskId);
10244                    }
10245                    return;
10246                }
10247
10248                final ActivityStack stack = mStackSupervisor.getFocusedStack();
10249                if (stack == null || task != stack.topTask()) {
10250                    throw new IllegalArgumentException("Invalid task, not in foreground");
10251                }
10252            }
10253            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10254                    "Locking fully");
10255            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10256                    ActivityManager.LOCK_TASK_MODE_PINNED :
10257                    ActivityManager.LOCK_TASK_MODE_LOCKED,
10258                    "startLockTask", true);
10259        } finally {
10260            Binder.restoreCallingIdentity(ident);
10261        }
10262    }
10263
10264    @Override
10265    public void startLockTaskModeById(int taskId) {
10266        synchronized (this) {
10267            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10268            if (task != null) {
10269                startLockTaskModeLocked(task);
10270            }
10271        }
10272    }
10273
10274    @Override
10275    public void startLockTaskModeByToken(IBinder token) {
10276        synchronized (this) {
10277            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10278            if (r == null) {
10279                return;
10280            }
10281            final TaskRecord task = r.task;
10282            if (task != null) {
10283                startLockTaskModeLocked(task);
10284            }
10285        }
10286    }
10287
10288    @Override
10289    public void startSystemLockTaskMode(int taskId) throws RemoteException {
10290        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10291        // This makes inner call to look as if it was initiated by system.
10292        long ident = Binder.clearCallingIdentity();
10293        try {
10294            synchronized (this) {
10295                startLockTaskModeById(taskId);
10296            }
10297        } finally {
10298            Binder.restoreCallingIdentity(ident);
10299        }
10300    }
10301
10302    @Override
10303    public void stopLockTaskMode() {
10304        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10305        if (lockTask == null) {
10306            // Our work here is done.
10307            return;
10308        }
10309
10310        final int callingUid = Binder.getCallingUid();
10311        final int lockTaskUid = lockTask.mLockTaskUid;
10312        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10313        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10314            // Done.
10315            return;
10316        } else {
10317            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10318            // It is possible lockTaskMode was started by the system process because
10319            // android:lockTaskMode is set to a locking value in the application manifest
10320            // instead of the app calling startLockTaskMode. In this case
10321            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10322            // {@link TaskRecord.effectiveUid} instead. Also caller with
10323            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10324            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10325                    && callingUid != lockTaskUid
10326                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10327                throw new SecurityException("Invalid uid, expected " + lockTaskUid
10328                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10329            }
10330        }
10331        long ident = Binder.clearCallingIdentity();
10332        try {
10333            Log.d(TAG, "stopLockTaskMode");
10334            // Stop lock task
10335            synchronized (this) {
10336                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10337                        "stopLockTask", true);
10338            }
10339            TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10340            if (tm != null) {
10341                tm.showInCallScreen(false);
10342            }
10343        } finally {
10344            Binder.restoreCallingIdentity(ident);
10345        }
10346    }
10347
10348    /**
10349     * This API should be called by SystemUI only when user perform certain action to dismiss
10350     * lock task mode. We should only dismiss pinned lock task mode in this case.
10351     */
10352    @Override
10353    public void stopSystemLockTaskMode() throws RemoteException {
10354        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10355            stopLockTaskMode();
10356        } else {
10357            mStackSupervisor.showLockTaskToast();
10358        }
10359    }
10360
10361    @Override
10362    public boolean isInLockTaskMode() {
10363        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10364    }
10365
10366    @Override
10367    public int getLockTaskModeState() {
10368        synchronized (this) {
10369            return mStackSupervisor.getLockTaskModeState();
10370        }
10371    }
10372
10373    @Override
10374    public void showLockTaskEscapeMessage(IBinder token) {
10375        synchronized (this) {
10376            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10377            if (r == null) {
10378                return;
10379            }
10380            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10381        }
10382    }
10383
10384    // =========================================================
10385    // CONTENT PROVIDERS
10386    // =========================================================
10387
10388    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10389        List<ProviderInfo> providers = null;
10390        try {
10391            providers = AppGlobals.getPackageManager()
10392                    .queryContentProviders(app.processName, app.uid,
10393                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10394                                    | MATCH_DEBUG_TRIAGED_MISSING)
10395                    .getList();
10396        } catch (RemoteException ex) {
10397        }
10398        if (DEBUG_MU) Slog.v(TAG_MU,
10399                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10400        int userId = app.userId;
10401        if (providers != null) {
10402            int N = providers.size();
10403            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10404            for (int i=0; i<N; i++) {
10405                // TODO: keep logic in sync with installEncryptionUnawareProviders
10406                ProviderInfo cpi =
10407                    (ProviderInfo)providers.get(i);
10408                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10409                        cpi.name, cpi.flags);
10410                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10411                    // This is a singleton provider, but a user besides the
10412                    // default user is asking to initialize a process it runs
10413                    // in...  well, no, it doesn't actually run in this process,
10414                    // it runs in the process of the default user.  Get rid of it.
10415                    providers.remove(i);
10416                    N--;
10417                    i--;
10418                    continue;
10419                }
10420
10421                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10422                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10423                if (cpr == null) {
10424                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10425                    mProviderMap.putProviderByClass(comp, cpr);
10426                }
10427                if (DEBUG_MU) Slog.v(TAG_MU,
10428                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10429                app.pubProviders.put(cpi.name, cpr);
10430                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10431                    // Don't add this if it is a platform component that is marked
10432                    // to run in multiple processes, because this is actually
10433                    // part of the framework so doesn't make sense to track as a
10434                    // separate apk in the process.
10435                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10436                            mProcessStats);
10437                }
10438                notifyPackageUse(cpi.applicationInfo.packageName,
10439                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10440            }
10441        }
10442        return providers;
10443    }
10444
10445    /**
10446     * Check if the calling UID has a possible chance at accessing the provider
10447     * at the given authority and user.
10448     */
10449    public String checkContentProviderAccess(String authority, int userId) {
10450        if (userId == UserHandle.USER_ALL) {
10451            mContext.enforceCallingOrSelfPermission(
10452                    Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
10453            userId = UserHandle.getCallingUserId();
10454        }
10455
10456        ProviderInfo cpi = null;
10457        try {
10458            cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
10459                    STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10460                            | PackageManager.MATCH_DIRECT_BOOT_AWARE
10461                            | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
10462                    userId);
10463        } catch (RemoteException ignored) {
10464        }
10465        if (cpi == null) {
10466            // TODO: make this an outright failure in a future platform release;
10467            // until then anonymous content notifications are unprotected
10468            //return "Failed to find provider " + authority + " for user " + userId;
10469            return null;
10470        }
10471
10472        ProcessRecord r = null;
10473        synchronized (mPidsSelfLocked) {
10474            r = mPidsSelfLocked.get(Binder.getCallingPid());
10475        }
10476        if (r == null) {
10477            return "Failed to find PID " + Binder.getCallingPid();
10478        }
10479
10480        synchronized (this) {
10481            return checkContentProviderPermissionLocked(cpi, r, userId, true);
10482        }
10483    }
10484
10485    /**
10486     * Check if {@link ProcessRecord} has a possible chance at accessing the
10487     * given {@link ProviderInfo}. Final permission checking is always done
10488     * in {@link ContentProvider}.
10489     */
10490    private final String checkContentProviderPermissionLocked(
10491            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10492        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10493        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10494        boolean checkedGrants = false;
10495        if (checkUser) {
10496            // Looking for cross-user grants before enforcing the typical cross-users permissions
10497            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10498            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10499                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10500                    return null;
10501                }
10502                checkedGrants = true;
10503            }
10504            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10505                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10506            if (userId != tmpTargetUserId) {
10507                // When we actually went to determine the final targer user ID, this ended
10508                // up different than our initial check for the authority.  This is because
10509                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10510                // SELF.  So we need to re-check the grants again.
10511                checkedGrants = false;
10512            }
10513        }
10514        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10515                cpi.applicationInfo.uid, cpi.exported)
10516                == PackageManager.PERMISSION_GRANTED) {
10517            return null;
10518        }
10519        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10520                cpi.applicationInfo.uid, cpi.exported)
10521                == PackageManager.PERMISSION_GRANTED) {
10522            return null;
10523        }
10524
10525        PathPermission[] pps = cpi.pathPermissions;
10526        if (pps != null) {
10527            int i = pps.length;
10528            while (i > 0) {
10529                i--;
10530                PathPermission pp = pps[i];
10531                String pprperm = pp.getReadPermission();
10532                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10533                        cpi.applicationInfo.uid, cpi.exported)
10534                        == PackageManager.PERMISSION_GRANTED) {
10535                    return null;
10536                }
10537                String ppwperm = pp.getWritePermission();
10538                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10539                        cpi.applicationInfo.uid, cpi.exported)
10540                        == PackageManager.PERMISSION_GRANTED) {
10541                    return null;
10542                }
10543            }
10544        }
10545        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10546            return null;
10547        }
10548
10549        String msg;
10550        if (!cpi.exported) {
10551            msg = "Permission Denial: opening provider " + cpi.name
10552                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10553                    + ", uid=" + callingUid + ") that is not exported from uid "
10554                    + cpi.applicationInfo.uid;
10555        } else {
10556            msg = "Permission Denial: opening provider " + cpi.name
10557                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10558                    + ", uid=" + callingUid + ") requires "
10559                    + cpi.readPermission + " or " + cpi.writePermission;
10560        }
10561        Slog.w(TAG, msg);
10562        return msg;
10563    }
10564
10565    /**
10566     * Returns if the ContentProvider has granted a uri to callingUid
10567     */
10568    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10569        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10570        if (perms != null) {
10571            for (int i=perms.size()-1; i>=0; i--) {
10572                GrantUri grantUri = perms.keyAt(i);
10573                if (grantUri.sourceUserId == userId || !checkUser) {
10574                    if (matchesProvider(grantUri.uri, cpi)) {
10575                        return true;
10576                    }
10577                }
10578            }
10579        }
10580        return false;
10581    }
10582
10583    /**
10584     * Returns true if the uri authority is one of the authorities specified in the provider.
10585     */
10586    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10587        String uriAuth = uri.getAuthority();
10588        String cpiAuth = cpi.authority;
10589        if (cpiAuth.indexOf(';') == -1) {
10590            return cpiAuth.equals(uriAuth);
10591        }
10592        String[] cpiAuths = cpiAuth.split(";");
10593        int length = cpiAuths.length;
10594        for (int i = 0; i < length; i++) {
10595            if (cpiAuths[i].equals(uriAuth)) return true;
10596        }
10597        return false;
10598    }
10599
10600    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10601            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10602        if (r != null) {
10603            for (int i=0; i<r.conProviders.size(); i++) {
10604                ContentProviderConnection conn = r.conProviders.get(i);
10605                if (conn.provider == cpr) {
10606                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10607                            "Adding provider requested by "
10608                            + r.processName + " from process "
10609                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10610                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10611                    if (stable) {
10612                        conn.stableCount++;
10613                        conn.numStableIncs++;
10614                    } else {
10615                        conn.unstableCount++;
10616                        conn.numUnstableIncs++;
10617                    }
10618                    return conn;
10619                }
10620            }
10621            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10622            if (stable) {
10623                conn.stableCount = 1;
10624                conn.numStableIncs = 1;
10625            } else {
10626                conn.unstableCount = 1;
10627                conn.numUnstableIncs = 1;
10628            }
10629            cpr.connections.add(conn);
10630            r.conProviders.add(conn);
10631            startAssociationLocked(r.uid, r.processName, r.curProcState,
10632                    cpr.uid, cpr.name, cpr.info.processName);
10633            return conn;
10634        }
10635        cpr.addExternalProcessHandleLocked(externalProcessToken);
10636        return null;
10637    }
10638
10639    boolean decProviderCountLocked(ContentProviderConnection conn,
10640            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10641        if (conn != null) {
10642            cpr = conn.provider;
10643            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10644                    "Removing provider requested by "
10645                    + conn.client.processName + " from process "
10646                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10647                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10648            if (stable) {
10649                conn.stableCount--;
10650            } else {
10651                conn.unstableCount--;
10652            }
10653            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10654                cpr.connections.remove(conn);
10655                conn.client.conProviders.remove(conn);
10656                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10657                    // The client is more important than last activity -- note the time this
10658                    // is happening, so we keep the old provider process around a bit as last
10659                    // activity to avoid thrashing it.
10660                    if (cpr.proc != null) {
10661                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10662                    }
10663                }
10664                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10665                return true;
10666            }
10667            return false;
10668        }
10669        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10670        return false;
10671    }
10672
10673    private void checkTime(long startTime, String where) {
10674        long now = SystemClock.uptimeMillis();
10675        if ((now-startTime) > 50) {
10676            // If we are taking more than 50ms, log about it.
10677            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10678        }
10679    }
10680
10681    private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
10682            PROC_SPACE_TERM,
10683            PROC_SPACE_TERM|PROC_PARENS,
10684            PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
10685    };
10686
10687    private final long[] mProcessStateStatsLongs = new long[1];
10688
10689    boolean isProcessAliveLocked(ProcessRecord proc) {
10690        if (proc.procStatFile == null) {
10691            proc.procStatFile = "/proc/" + proc.pid + "/stat";
10692        }
10693        mProcessStateStatsLongs[0] = 0;
10694        if (!Process.readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
10695                mProcessStateStatsLongs, null)) {
10696            if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
10697            return false;
10698        }
10699        final long state = mProcessStateStatsLongs[0];
10700        if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
10701                + (char)state);
10702        return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
10703    }
10704
10705    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10706            String name, IBinder token, boolean stable, int userId) {
10707        ContentProviderRecord cpr;
10708        ContentProviderConnection conn = null;
10709        ProviderInfo cpi = null;
10710
10711        synchronized(this) {
10712            long startTime = SystemClock.uptimeMillis();
10713
10714            ProcessRecord r = null;
10715            if (caller != null) {
10716                r = getRecordForAppLocked(caller);
10717                if (r == null) {
10718                    throw new SecurityException(
10719                            "Unable to find app for caller " + caller
10720                          + " (pid=" + Binder.getCallingPid()
10721                          + ") when getting content provider " + name);
10722                }
10723            }
10724
10725            boolean checkCrossUser = true;
10726
10727            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10728
10729            // First check if this content provider has been published...
10730            cpr = mProviderMap.getProviderByName(name, userId);
10731            // If that didn't work, check if it exists for user 0 and then
10732            // verify that it's a singleton provider before using it.
10733            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10734                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10735                if (cpr != null) {
10736                    cpi = cpr.info;
10737                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10738                            cpi.name, cpi.flags)
10739                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10740                        userId = UserHandle.USER_SYSTEM;
10741                        checkCrossUser = false;
10742                    } else {
10743                        cpr = null;
10744                        cpi = null;
10745                    }
10746                }
10747            }
10748
10749            boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
10750            if (providerRunning) {
10751                cpi = cpr.info;
10752                String msg;
10753                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10754                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10755                        != null) {
10756                    throw new SecurityException(msg);
10757                }
10758                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10759
10760                if (r != null && cpr.canRunHere(r)) {
10761                    // This provider has been published or is in the process
10762                    // of being published...  but it is also allowed to run
10763                    // in the caller's process, so don't make a connection
10764                    // and just let the caller instantiate its own instance.
10765                    ContentProviderHolder holder = cpr.newHolder(null);
10766                    // don't give caller the provider object, it needs
10767                    // to make its own.
10768                    holder.provider = null;
10769                    return holder;
10770                }
10771
10772                final long origId = Binder.clearCallingIdentity();
10773
10774                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10775
10776                // In this case the provider instance already exists, so we can
10777                // return it right away.
10778                conn = incProviderCountLocked(r, cpr, token, stable);
10779                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10780                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10781                        // If this is a perceptible app accessing the provider,
10782                        // make sure to count it as being accessed and thus
10783                        // back up on the LRU list.  This is good because
10784                        // content providers are often expensive to start.
10785                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10786                        updateLruProcessLocked(cpr.proc, false, null);
10787                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10788                    }
10789                }
10790
10791                checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10792                final int verifiedAdj = cpr.proc.verifiedAdj;
10793                boolean success = updateOomAdjLocked(cpr.proc);
10794                // XXX things have changed so updateOomAdjLocked doesn't actually tell us
10795                // if the process has been successfully adjusted.  So to reduce races with
10796                // it, we will check whether the process still exists.  Note that this doesn't
10797                // completely get rid of races with LMK killing the process, but should make
10798                // them much smaller.
10799                if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
10800                    success = false;
10801                }
10802                maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10803                checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10804                if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10805                // NOTE: there is still a race here where a signal could be
10806                // pending on the process even though we managed to update its
10807                // adj level.  Not sure what to do about this, but at least
10808                // the race is now smaller.
10809                if (!success) {
10810                    // Uh oh...  it looks like the provider's process
10811                    // has been killed on us.  We need to wait for a new
10812                    // process to be started, and make sure its death
10813                    // doesn't kill our process.
10814                    Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10815                            + " is crashing; detaching " + r);
10816                    boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10817                    checkTime(startTime, "getContentProviderImpl: before appDied");
10818                    appDiedLocked(cpr.proc);
10819                    checkTime(startTime, "getContentProviderImpl: after appDied");
10820                    if (!lastRef) {
10821                        // This wasn't the last ref our process had on
10822                        // the provider...  we have now been killed, bail.
10823                        return null;
10824                    }
10825                    providerRunning = false;
10826                    conn = null;
10827                } else {
10828                    cpr.proc.verifiedAdj = cpr.proc.setAdj;
10829                }
10830
10831                Binder.restoreCallingIdentity(origId);
10832            }
10833
10834            if (!providerRunning) {
10835                try {
10836                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10837                    cpi = AppGlobals.getPackageManager().
10838                        resolveContentProvider(name,
10839                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10840                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10841                } catch (RemoteException ex) {
10842                }
10843                if (cpi == null) {
10844                    return null;
10845                }
10846                // If the provider is a singleton AND
10847                // (it's a call within the same user || the provider is a
10848                // privileged app)
10849                // Then allow connecting to the singleton provider
10850                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10851                        cpi.name, cpi.flags)
10852                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10853                if (singleton) {
10854                    userId = UserHandle.USER_SYSTEM;
10855                }
10856                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10857                checkTime(startTime, "getContentProviderImpl: got app info for user");
10858
10859                String msg;
10860                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10861                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10862                        != null) {
10863                    throw new SecurityException(msg);
10864                }
10865                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10866
10867                if (!mProcessesReady
10868                        && !cpi.processName.equals("system")) {
10869                    // If this content provider does not run in the system
10870                    // process, and the system is not yet ready to run other
10871                    // processes, then fail fast instead of hanging.
10872                    throw new IllegalArgumentException(
10873                            "Attempt to launch content provider before system ready");
10874                }
10875
10876                // Make sure that the user who owns this provider is running.  If not,
10877                // we don't want to allow it to run.
10878                if (!mUserController.isUserRunningLocked(userId, 0)) {
10879                    Slog.w(TAG, "Unable to launch app "
10880                            + cpi.applicationInfo.packageName + "/"
10881                            + cpi.applicationInfo.uid + " for provider "
10882                            + name + ": user " + userId + " is stopped");
10883                    return null;
10884                }
10885
10886                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10887                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10888                cpr = mProviderMap.getProviderByClass(comp, userId);
10889                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10890                final boolean firstClass = cpr == null;
10891                if (firstClass) {
10892                    final long ident = Binder.clearCallingIdentity();
10893
10894                    // If permissions need a review before any of the app components can run,
10895                    // we return no provider and launch a review activity if the calling app
10896                    // is in the foreground.
10897                    if (mPermissionReviewRequired) {
10898                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10899                            return null;
10900                        }
10901                    }
10902
10903                    try {
10904                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10905                        ApplicationInfo ai =
10906                            AppGlobals.getPackageManager().
10907                                getApplicationInfo(
10908                                        cpi.applicationInfo.packageName,
10909                                        STOCK_PM_FLAGS, userId);
10910                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10911                        if (ai == null) {
10912                            Slog.w(TAG, "No package info for content provider "
10913                                    + cpi.name);
10914                            return null;
10915                        }
10916                        ai = getAppInfoForUser(ai, userId);
10917                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10918                    } catch (RemoteException ex) {
10919                        // pm is in same process, this will never happen.
10920                    } finally {
10921                        Binder.restoreCallingIdentity(ident);
10922                    }
10923                }
10924
10925                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10926
10927                if (r != null && cpr.canRunHere(r)) {
10928                    // If this is a multiprocess provider, then just return its
10929                    // info and allow the caller to instantiate it.  Only do
10930                    // this if the provider is the same user as the caller's
10931                    // process, or can run as root (so can be in any process).
10932                    return cpr.newHolder(null);
10933                }
10934
10935                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10936                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10937                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10938
10939                // This is single process, and our app is now connecting to it.
10940                // See if we are already in the process of launching this
10941                // provider.
10942                final int N = mLaunchingProviders.size();
10943                int i;
10944                for (i = 0; i < N; i++) {
10945                    if (mLaunchingProviders.get(i) == cpr) {
10946                        break;
10947                    }
10948                }
10949
10950                // If the provider is not already being launched, then get it
10951                // started.
10952                if (i >= N) {
10953                    final long origId = Binder.clearCallingIdentity();
10954
10955                    try {
10956                        // Content provider is now in use, its package can't be stopped.
10957                        try {
10958                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10959                            AppGlobals.getPackageManager().setPackageStoppedState(
10960                                    cpr.appInfo.packageName, false, userId);
10961                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10962                        } catch (RemoteException e) {
10963                        } catch (IllegalArgumentException e) {
10964                            Slog.w(TAG, "Failed trying to unstop package "
10965                                    + cpr.appInfo.packageName + ": " + e);
10966                        }
10967
10968                        // Use existing process if already started
10969                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10970                        ProcessRecord proc = getProcessRecordLocked(
10971                                cpi.processName, cpr.appInfo.uid, false);
10972                        if (proc != null && proc.thread != null && !proc.killed) {
10973                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10974                                    "Installing in existing process " + proc);
10975                            if (!proc.pubProviders.containsKey(cpi.name)) {
10976                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10977                                proc.pubProviders.put(cpi.name, cpr);
10978                                try {
10979                                    proc.thread.scheduleInstallProvider(cpi);
10980                                } catch (RemoteException e) {
10981                                }
10982                            }
10983                        } else {
10984                            checkTime(startTime, "getContentProviderImpl: before start process");
10985                            proc = startProcessLocked(cpi.processName,
10986                                    cpr.appInfo, false, 0, "content provider",
10987                                    new ComponentName(cpi.applicationInfo.packageName,
10988                                            cpi.name), false, false, false);
10989                            checkTime(startTime, "getContentProviderImpl: after start process");
10990                            if (proc == null) {
10991                                Slog.w(TAG, "Unable to launch app "
10992                                        + cpi.applicationInfo.packageName + "/"
10993                                        + cpi.applicationInfo.uid + " for provider "
10994                                        + name + ": process is bad");
10995                                return null;
10996                            }
10997                        }
10998                        cpr.launchingApp = proc;
10999                        mLaunchingProviders.add(cpr);
11000                    } finally {
11001                        Binder.restoreCallingIdentity(origId);
11002                    }
11003                }
11004
11005                checkTime(startTime, "getContentProviderImpl: updating data structures");
11006
11007                // Make sure the provider is published (the same provider class
11008                // may be published under multiple names).
11009                if (firstClass) {
11010                    mProviderMap.putProviderByClass(comp, cpr);
11011                }
11012
11013                mProviderMap.putProviderByName(name, cpr);
11014                conn = incProviderCountLocked(r, cpr, token, stable);
11015                if (conn != null) {
11016                    conn.waiting = true;
11017                }
11018            }
11019            checkTime(startTime, "getContentProviderImpl: done!");
11020        }
11021
11022        // Wait for the provider to be published...
11023        synchronized (cpr) {
11024            while (cpr.provider == null) {
11025                if (cpr.launchingApp == null) {
11026                    Slog.w(TAG, "Unable to launch app "
11027                            + cpi.applicationInfo.packageName + "/"
11028                            + cpi.applicationInfo.uid + " for provider "
11029                            + name + ": launching app became null");
11030                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
11031                            UserHandle.getUserId(cpi.applicationInfo.uid),
11032                            cpi.applicationInfo.packageName,
11033                            cpi.applicationInfo.uid, name);
11034                    return null;
11035                }
11036                try {
11037                    if (DEBUG_MU) Slog.v(TAG_MU,
11038                            "Waiting to start provider " + cpr
11039                            + " launchingApp=" + cpr.launchingApp);
11040                    if (conn != null) {
11041                        conn.waiting = true;
11042                    }
11043                    cpr.wait();
11044                } catch (InterruptedException ex) {
11045                } finally {
11046                    if (conn != null) {
11047                        conn.waiting = false;
11048                    }
11049                }
11050            }
11051        }
11052        return cpr != null ? cpr.newHolder(conn) : null;
11053    }
11054
11055    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
11056            ProcessRecord r, final int userId) {
11057        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
11058                cpi.packageName, userId)) {
11059
11060            final boolean callerForeground = r == null || r.setSchedGroup
11061                    != ProcessList.SCHED_GROUP_BACKGROUND;
11062
11063            // Show a permission review UI only for starting from a foreground app
11064            if (!callerForeground) {
11065                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
11066                        + cpi.packageName + " requires a permissions review");
11067                return false;
11068            }
11069
11070            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
11071            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11072                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
11073            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
11074
11075            if (DEBUG_PERMISSIONS_REVIEW) {
11076                Slog.i(TAG, "u" + userId + " Launching permission review "
11077                        + "for package " + cpi.packageName);
11078            }
11079
11080            final UserHandle userHandle = new UserHandle(userId);
11081            mHandler.post(new Runnable() {
11082                @Override
11083                public void run() {
11084                    mContext.startActivityAsUser(intent, userHandle);
11085                }
11086            });
11087
11088            return false;
11089        }
11090
11091        return true;
11092    }
11093
11094    PackageManagerInternal getPackageManagerInternalLocked() {
11095        if (mPackageManagerInt == null) {
11096            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
11097        }
11098        return mPackageManagerInt;
11099    }
11100
11101    @Override
11102    public final ContentProviderHolder getContentProvider(
11103            IApplicationThread caller, String name, int userId, boolean stable) {
11104        enforceNotIsolatedCaller("getContentProvider");
11105        if (caller == null) {
11106            String msg = "null IApplicationThread when getting content provider "
11107                    + name;
11108            Slog.w(TAG, msg);
11109            throw new SecurityException(msg);
11110        }
11111        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
11112        // with cross-user grant.
11113        return getContentProviderImpl(caller, name, null, stable, userId);
11114    }
11115
11116    public ContentProviderHolder getContentProviderExternal(
11117            String name, int userId, IBinder token) {
11118        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11119            "Do not have permission in call getContentProviderExternal()");
11120        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
11121                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
11122        return getContentProviderExternalUnchecked(name, token, userId);
11123    }
11124
11125    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
11126            IBinder token, int userId) {
11127        return getContentProviderImpl(null, name, token, true, userId);
11128    }
11129
11130    /**
11131     * Drop a content provider from a ProcessRecord's bookkeeping
11132     */
11133    public void removeContentProvider(IBinder connection, boolean stable) {
11134        enforceNotIsolatedCaller("removeContentProvider");
11135        long ident = Binder.clearCallingIdentity();
11136        try {
11137            synchronized (this) {
11138                ContentProviderConnection conn;
11139                try {
11140                    conn = (ContentProviderConnection)connection;
11141                } catch (ClassCastException e) {
11142                    String msg ="removeContentProvider: " + connection
11143                            + " not a ContentProviderConnection";
11144                    Slog.w(TAG, msg);
11145                    throw new IllegalArgumentException(msg);
11146                }
11147                if (conn == null) {
11148                    throw new NullPointerException("connection is null");
11149                }
11150                if (decProviderCountLocked(conn, null, null, stable)) {
11151                    updateOomAdjLocked();
11152                }
11153            }
11154        } finally {
11155            Binder.restoreCallingIdentity(ident);
11156        }
11157    }
11158
11159    public void removeContentProviderExternal(String name, IBinder token) {
11160        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11161            "Do not have permission in call removeContentProviderExternal()");
11162        int userId = UserHandle.getCallingUserId();
11163        long ident = Binder.clearCallingIdentity();
11164        try {
11165            removeContentProviderExternalUnchecked(name, token, userId);
11166        } finally {
11167            Binder.restoreCallingIdentity(ident);
11168        }
11169    }
11170
11171    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11172        synchronized (this) {
11173            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11174            if(cpr == null) {
11175                //remove from mProvidersByClass
11176                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11177                return;
11178            }
11179
11180            //update content provider record entry info
11181            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11182            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11183            if (localCpr.hasExternalProcessHandles()) {
11184                if (localCpr.removeExternalProcessHandleLocked(token)) {
11185                    updateOomAdjLocked();
11186                } else {
11187                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11188                            + " with no external reference for token: "
11189                            + token + ".");
11190                }
11191            } else {
11192                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11193                        + " with no external references.");
11194            }
11195        }
11196    }
11197
11198    public final void publishContentProviders(IApplicationThread caller,
11199            List<ContentProviderHolder> providers) {
11200        if (providers == null) {
11201            return;
11202        }
11203
11204        enforceNotIsolatedCaller("publishContentProviders");
11205        synchronized (this) {
11206            final ProcessRecord r = getRecordForAppLocked(caller);
11207            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11208            if (r == null) {
11209                throw new SecurityException(
11210                        "Unable to find app for caller " + caller
11211                      + " (pid=" + Binder.getCallingPid()
11212                      + ") when publishing content providers");
11213            }
11214
11215            final long origId = Binder.clearCallingIdentity();
11216
11217            final int N = providers.size();
11218            for (int i = 0; i < N; i++) {
11219                ContentProviderHolder src = providers.get(i);
11220                if (src == null || src.info == null || src.provider == null) {
11221                    continue;
11222                }
11223                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11224                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11225                if (dst != null) {
11226                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11227                    mProviderMap.putProviderByClass(comp, dst);
11228                    String names[] = dst.info.authority.split(";");
11229                    for (int j = 0; j < names.length; j++) {
11230                        mProviderMap.putProviderByName(names[j], dst);
11231                    }
11232
11233                    int launchingCount = mLaunchingProviders.size();
11234                    int j;
11235                    boolean wasInLaunchingProviders = false;
11236                    for (j = 0; j < launchingCount; j++) {
11237                        if (mLaunchingProviders.get(j) == dst) {
11238                            mLaunchingProviders.remove(j);
11239                            wasInLaunchingProviders = true;
11240                            j--;
11241                            launchingCount--;
11242                        }
11243                    }
11244                    if (wasInLaunchingProviders) {
11245                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11246                    }
11247                    synchronized (dst) {
11248                        dst.provider = src.provider;
11249                        dst.proc = r;
11250                        dst.notifyAll();
11251                    }
11252                    updateOomAdjLocked(r);
11253                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11254                            src.info.authority);
11255                }
11256            }
11257
11258            Binder.restoreCallingIdentity(origId);
11259        }
11260    }
11261
11262    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11263        ContentProviderConnection conn;
11264        try {
11265            conn = (ContentProviderConnection)connection;
11266        } catch (ClassCastException e) {
11267            String msg ="refContentProvider: " + connection
11268                    + " not a ContentProviderConnection";
11269            Slog.w(TAG, msg);
11270            throw new IllegalArgumentException(msg);
11271        }
11272        if (conn == null) {
11273            throw new NullPointerException("connection is null");
11274        }
11275
11276        synchronized (this) {
11277            if (stable > 0) {
11278                conn.numStableIncs += stable;
11279            }
11280            stable = conn.stableCount + stable;
11281            if (stable < 0) {
11282                throw new IllegalStateException("stableCount < 0: " + stable);
11283            }
11284
11285            if (unstable > 0) {
11286                conn.numUnstableIncs += unstable;
11287            }
11288            unstable = conn.unstableCount + unstable;
11289            if (unstable < 0) {
11290                throw new IllegalStateException("unstableCount < 0: " + unstable);
11291            }
11292
11293            if ((stable+unstable) <= 0) {
11294                throw new IllegalStateException("ref counts can't go to zero here: stable="
11295                        + stable + " unstable=" + unstable);
11296            }
11297            conn.stableCount = stable;
11298            conn.unstableCount = unstable;
11299            return !conn.dead;
11300        }
11301    }
11302
11303    public void unstableProviderDied(IBinder connection) {
11304        ContentProviderConnection conn;
11305        try {
11306            conn = (ContentProviderConnection)connection;
11307        } catch (ClassCastException e) {
11308            String msg ="refContentProvider: " + connection
11309                    + " not a ContentProviderConnection";
11310            Slog.w(TAG, msg);
11311            throw new IllegalArgumentException(msg);
11312        }
11313        if (conn == null) {
11314            throw new NullPointerException("connection is null");
11315        }
11316
11317        // Safely retrieve the content provider associated with the connection.
11318        IContentProvider provider;
11319        synchronized (this) {
11320            provider = conn.provider.provider;
11321        }
11322
11323        if (provider == null) {
11324            // Um, yeah, we're way ahead of you.
11325            return;
11326        }
11327
11328        // Make sure the caller is being honest with us.
11329        if (provider.asBinder().pingBinder()) {
11330            // Er, no, still looks good to us.
11331            synchronized (this) {
11332                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11333                        + " says " + conn + " died, but we don't agree");
11334                return;
11335            }
11336        }
11337
11338        // Well look at that!  It's dead!
11339        synchronized (this) {
11340            if (conn.provider.provider != provider) {
11341                // But something changed...  good enough.
11342                return;
11343            }
11344
11345            ProcessRecord proc = conn.provider.proc;
11346            if (proc == null || proc.thread == null) {
11347                // Seems like the process is already cleaned up.
11348                return;
11349            }
11350
11351            // As far as we're concerned, this is just like receiving a
11352            // death notification...  just a bit prematurely.
11353            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11354                    + ") early provider death");
11355            final long ident = Binder.clearCallingIdentity();
11356            try {
11357                appDiedLocked(proc);
11358            } finally {
11359                Binder.restoreCallingIdentity(ident);
11360            }
11361        }
11362    }
11363
11364    @Override
11365    public void appNotRespondingViaProvider(IBinder connection) {
11366        enforceCallingPermission(
11367                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11368
11369        final ContentProviderConnection conn = (ContentProviderConnection) connection;
11370        if (conn == null) {
11371            Slog.w(TAG, "ContentProviderConnection is null");
11372            return;
11373        }
11374
11375        final ProcessRecord host = conn.provider.proc;
11376        if (host == null) {
11377            Slog.w(TAG, "Failed to find hosting ProcessRecord");
11378            return;
11379        }
11380
11381        mHandler.post(new Runnable() {
11382            @Override
11383            public void run() {
11384                mAppErrors.appNotResponding(host, null, null, false,
11385                        "ContentProvider not responding");
11386            }
11387        });
11388    }
11389
11390    public final void installSystemProviders() {
11391        List<ProviderInfo> providers;
11392        synchronized (this) {
11393            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11394            providers = generateApplicationProvidersLocked(app);
11395            if (providers != null) {
11396                for (int i=providers.size()-1; i>=0; i--) {
11397                    ProviderInfo pi = (ProviderInfo)providers.get(i);
11398                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11399                        Slog.w(TAG, "Not installing system proc provider " + pi.name
11400                                + ": not system .apk");
11401                        providers.remove(i);
11402                    }
11403                }
11404            }
11405        }
11406        if (providers != null) {
11407            mSystemThread.installSystemProviders(providers);
11408        }
11409
11410        mCoreSettingsObserver = new CoreSettingsObserver(this);
11411        mFontScaleSettingObserver = new FontScaleSettingObserver();
11412
11413        //mUsageStatsService.monitorPackages();
11414    }
11415
11416    private void startPersistentApps(int matchFlags) {
11417        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11418
11419        synchronized (this) {
11420            try {
11421                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11422                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11423                for (ApplicationInfo app : apps) {
11424                    if (!"android".equals(app.packageName)) {
11425                        addAppLocked(app, false, null /* ABI override */);
11426                    }
11427                }
11428            } catch (RemoteException ex) {
11429            }
11430        }
11431    }
11432
11433    /**
11434     * When a user is unlocked, we need to install encryption-unaware providers
11435     * belonging to any running apps.
11436     */
11437    private void installEncryptionUnawareProviders(int userId) {
11438        // We're only interested in providers that are encryption unaware, and
11439        // we don't care about uninstalled apps, since there's no way they're
11440        // running at this point.
11441        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11442
11443        synchronized (this) {
11444            final int NP = mProcessNames.getMap().size();
11445            for (int ip = 0; ip < NP; ip++) {
11446                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11447                final int NA = apps.size();
11448                for (int ia = 0; ia < NA; ia++) {
11449                    final ProcessRecord app = apps.valueAt(ia);
11450                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11451
11452                    final int NG = app.pkgList.size();
11453                    for (int ig = 0; ig < NG; ig++) {
11454                        try {
11455                            final String pkgName = app.pkgList.keyAt(ig);
11456                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11457                                    .getPackageInfo(pkgName, matchFlags, userId);
11458                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11459                                for (ProviderInfo pi : pkgInfo.providers) {
11460                                    // TODO: keep in sync with generateApplicationProvidersLocked
11461                                    final boolean processMatch = Objects.equals(pi.processName,
11462                                            app.processName) || pi.multiprocess;
11463                                    final boolean userMatch = isSingleton(pi.processName,
11464                                            pi.applicationInfo, pi.name, pi.flags)
11465                                                    ? (app.userId == UserHandle.USER_SYSTEM) : true;
11466                                    if (processMatch && userMatch) {
11467                                        Log.v(TAG, "Installing " + pi);
11468                                        app.thread.scheduleInstallProvider(pi);
11469                                    } else {
11470                                        Log.v(TAG, "Skipping " + pi);
11471                                    }
11472                                }
11473                            }
11474                        } catch (RemoteException ignored) {
11475                        }
11476                    }
11477                }
11478            }
11479        }
11480    }
11481
11482    /**
11483     * Allows apps to retrieve the MIME type of a URI.
11484     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11485     * users, then it does not need permission to access the ContentProvider.
11486     * Either, it needs cross-user uri grants.
11487     *
11488     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11489     *
11490     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11491     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11492     */
11493    public String getProviderMimeType(Uri uri, int userId) {
11494        enforceNotIsolatedCaller("getProviderMimeType");
11495        final String name = uri.getAuthority();
11496        int callingUid = Binder.getCallingUid();
11497        int callingPid = Binder.getCallingPid();
11498        long ident = 0;
11499        boolean clearedIdentity = false;
11500        synchronized (this) {
11501            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11502        }
11503        if (canClearIdentity(callingPid, callingUid, userId)) {
11504            clearedIdentity = true;
11505            ident = Binder.clearCallingIdentity();
11506        }
11507        ContentProviderHolder holder = null;
11508        try {
11509            holder = getContentProviderExternalUnchecked(name, null, userId);
11510            if (holder != null) {
11511                return holder.provider.getType(uri);
11512            }
11513        } catch (RemoteException e) {
11514            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11515            return null;
11516        } catch (Exception e) {
11517            Log.w(TAG, "Exception while determining type of " + uri, e);
11518            return null;
11519        } finally {
11520            // We need to clear the identity to call removeContentProviderExternalUnchecked
11521            if (!clearedIdentity) {
11522                ident = Binder.clearCallingIdentity();
11523            }
11524            try {
11525                if (holder != null) {
11526                    removeContentProviderExternalUnchecked(name, null, userId);
11527                }
11528            } finally {
11529                Binder.restoreCallingIdentity(ident);
11530            }
11531        }
11532
11533        return null;
11534    }
11535
11536    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11537        if (UserHandle.getUserId(callingUid) == userId) {
11538            return true;
11539        }
11540        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11541                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11542                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11543                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11544                return true;
11545        }
11546        return false;
11547    }
11548
11549    // =========================================================
11550    // GLOBAL MANAGEMENT
11551    // =========================================================
11552
11553    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11554            boolean isolated, int isolatedUid) {
11555        String proc = customProcess != null ? customProcess : info.processName;
11556        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11557        final int userId = UserHandle.getUserId(info.uid);
11558        int uid = info.uid;
11559        if (isolated) {
11560            if (isolatedUid == 0) {
11561                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11562                while (true) {
11563                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11564                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11565                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11566                    }
11567                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11568                    mNextIsolatedProcessUid++;
11569                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11570                        // No process for this uid, use it.
11571                        break;
11572                    }
11573                    stepsLeft--;
11574                    if (stepsLeft <= 0) {
11575                        return null;
11576                    }
11577                }
11578            } else {
11579                // Special case for startIsolatedProcess (internal only), where
11580                // the uid of the isolated process is specified by the caller.
11581                uid = isolatedUid;
11582            }
11583
11584            // Register the isolated UID with this application so BatteryStats knows to
11585            // attribute resource usage to the application.
11586            //
11587            // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
11588            // about the process state of the isolated UID *before* it is registered with the
11589            // owning application.
11590            mBatteryStatsService.addIsolatedUid(uid, info.uid);
11591        }
11592        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11593        if (!mBooted && !mBooting
11594                && userId == UserHandle.USER_SYSTEM
11595                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11596            r.persistent = true;
11597            r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11598        }
11599        addProcessNameLocked(r);
11600        return r;
11601    }
11602
11603    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11604            String abiOverride) {
11605        ProcessRecord app;
11606        if (!isolated) {
11607            app = getProcessRecordLocked(info.processName, info.uid, true);
11608        } else {
11609            app = null;
11610        }
11611
11612        if (app == null) {
11613            app = newProcessRecordLocked(info, null, isolated, 0);
11614            updateLruProcessLocked(app, false, null);
11615            updateOomAdjLocked();
11616        }
11617
11618        // This package really, really can not be stopped.
11619        try {
11620            AppGlobals.getPackageManager().setPackageStoppedState(
11621                    info.packageName, false, UserHandle.getUserId(app.uid));
11622        } catch (RemoteException e) {
11623        } catch (IllegalArgumentException e) {
11624            Slog.w(TAG, "Failed trying to unstop package "
11625                    + info.packageName + ": " + e);
11626        }
11627
11628        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11629            app.persistent = true;
11630            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11631        }
11632        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11633            mPersistentStartingProcesses.add(app);
11634            startProcessLocked(app, "added application", app.processName, abiOverride,
11635                    null /* entryPoint */, null /* entryPointArgs */);
11636        }
11637
11638        return app;
11639    }
11640
11641    public void unhandledBack() {
11642        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11643                "unhandledBack()");
11644
11645        synchronized(this) {
11646            final long origId = Binder.clearCallingIdentity();
11647            try {
11648                getFocusedStack().unhandledBackLocked();
11649            } finally {
11650                Binder.restoreCallingIdentity(origId);
11651            }
11652        }
11653    }
11654
11655    public ParcelFileDescriptor openContentUri(String uriString) throws RemoteException {
11656        enforceNotIsolatedCaller("openContentUri");
11657        final int userId = UserHandle.getCallingUserId();
11658        final Uri uri = Uri.parse(uriString);
11659        String name = uri.getAuthority();
11660        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11661        ParcelFileDescriptor pfd = null;
11662        if (cph != null) {
11663            // We record the binder invoker's uid in thread-local storage before
11664            // going to the content provider to open the file.  Later, in the code
11665            // that handles all permissions checks, we look for this uid and use
11666            // that rather than the Activity Manager's own uid.  The effect is that
11667            // we do the check against the caller's permissions even though it looks
11668            // to the content provider like the Activity Manager itself is making
11669            // the request.
11670            Binder token = new Binder();
11671            sCallerIdentity.set(new Identity(
11672                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11673            try {
11674                pfd = cph.provider.openFile(null, uri, "r", null, token);
11675            } catch (FileNotFoundException e) {
11676                // do nothing; pfd will be returned null
11677            } finally {
11678                // Ensure that whatever happens, we clean up the identity state
11679                sCallerIdentity.remove();
11680                // Ensure we're done with the provider.
11681                removeContentProviderExternalUnchecked(name, null, userId);
11682            }
11683        } else {
11684            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11685        }
11686        return pfd;
11687    }
11688
11689    // Actually is sleeping or shutting down or whatever else in the future
11690    // is an inactive state.
11691    boolean isSleepingOrShuttingDownLocked() {
11692        return isSleepingLocked() || mShuttingDown;
11693    }
11694
11695    boolean isShuttingDownLocked() {
11696        return mShuttingDown;
11697    }
11698
11699    boolean isSleepingLocked() {
11700        return mSleeping;
11701    }
11702
11703    void onWakefulnessChanged(int wakefulness) {
11704        synchronized(this) {
11705            mWakefulness = wakefulness;
11706            updateSleepIfNeededLocked();
11707        }
11708    }
11709
11710    void finishRunningVoiceLocked() {
11711        if (mRunningVoice != null) {
11712            mRunningVoice = null;
11713            mVoiceWakeLock.release();
11714            updateSleepIfNeededLocked();
11715        }
11716    }
11717
11718    void startTimeTrackingFocusedActivityLocked() {
11719        final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked();
11720        if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
11721            mCurAppTimeTracker.start(resumedActivity.packageName);
11722        }
11723    }
11724
11725    void updateSleepIfNeededLocked() {
11726        if (mSleeping && !shouldSleepLocked()) {
11727            mSleeping = false;
11728            startTimeTrackingFocusedActivityLocked();
11729            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11730            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11731            sendNotifyVrManagerOfSleepState(false);
11732            updateOomAdjLocked();
11733        } else if (!mSleeping && shouldSleepLocked()) {
11734            mSleeping = true;
11735            if (mCurAppTimeTracker != null) {
11736                mCurAppTimeTracker.stop();
11737            }
11738            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11739            mStackSupervisor.goingToSleepLocked();
11740            sendNotifyVrManagerOfSleepState(true);
11741            updateOomAdjLocked();
11742
11743            // Initialize the wake times of all processes.
11744            checkExcessivePowerUsageLocked(false);
11745            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11746            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11747            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11748        }
11749    }
11750
11751    private boolean shouldSleepLocked() {
11752        // Resume applications while running a voice interactor.
11753        if (mRunningVoice != null) {
11754            return false;
11755        }
11756
11757        // TODO: Transform the lock screen state into a sleep token instead.
11758        switch (mWakefulness) {
11759            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11760            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11761            case PowerManagerInternal.WAKEFULNESS_DOZING:
11762                // Pause applications whenever the lock screen is shown or any sleep
11763                // tokens have been acquired.
11764                return mKeyguardController.isKeyguardShowing() || !mSleepTokens.isEmpty();
11765            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11766            default:
11767                // If we're asleep then pause applications unconditionally.
11768                return true;
11769        }
11770    }
11771
11772    /** Pokes the task persister. */
11773    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11774        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11775    }
11776
11777    /** Notifies all listeners when the pinned stack animation ends. */
11778    @Override
11779    public void notifyPinnedStackAnimationEnded() {
11780        mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
11781    }
11782
11783    @Override
11784    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11785        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11786    }
11787
11788    @Override
11789    public boolean shutdown(int timeout) {
11790        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11791                != PackageManager.PERMISSION_GRANTED) {
11792            throw new SecurityException("Requires permission "
11793                    + android.Manifest.permission.SHUTDOWN);
11794        }
11795
11796        boolean timedout = false;
11797
11798        synchronized(this) {
11799            mShuttingDown = true;
11800            updateEventDispatchingLocked();
11801            timedout = mStackSupervisor.shutdownLocked(timeout);
11802        }
11803
11804        mAppOpsService.shutdown();
11805        if (mUsageStatsService != null) {
11806            mUsageStatsService.prepareShutdown();
11807        }
11808        mBatteryStatsService.shutdown();
11809        synchronized (this) {
11810            mProcessStats.shutdownLocked();
11811            notifyTaskPersisterLocked(null, true);
11812        }
11813
11814        return timedout;
11815    }
11816
11817    public final void activitySlept(IBinder token) {
11818        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11819
11820        final long origId = Binder.clearCallingIdentity();
11821
11822        synchronized (this) {
11823            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11824            if (r != null) {
11825                mStackSupervisor.activitySleptLocked(r);
11826            }
11827        }
11828
11829        Binder.restoreCallingIdentity(origId);
11830    }
11831
11832    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11833        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11834        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11835        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11836            boolean wasRunningVoice = mRunningVoice != null;
11837            mRunningVoice = session;
11838            if (!wasRunningVoice) {
11839                mVoiceWakeLock.acquire();
11840                updateSleepIfNeededLocked();
11841            }
11842        }
11843    }
11844
11845    private void updateEventDispatchingLocked() {
11846        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11847    }
11848
11849    @Override
11850    public void setLockScreenShown(boolean showing) {
11851        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11852                != PackageManager.PERMISSION_GRANTED) {
11853            throw new SecurityException("Requires permission "
11854                    + android.Manifest.permission.DEVICE_POWER);
11855        }
11856
11857        synchronized(this) {
11858            long ident = Binder.clearCallingIdentity();
11859            try {
11860                mKeyguardController.setKeyguardShown(showing);
11861            } finally {
11862                Binder.restoreCallingIdentity(ident);
11863            }
11864        }
11865    }
11866
11867    @Override
11868    public void notifyLockedProfile(@UserIdInt int userId) {
11869        try {
11870            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11871                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11872            }
11873        } catch (RemoteException ex) {
11874            throw new SecurityException("Fail to check is caller a privileged app", ex);
11875        }
11876
11877        synchronized (this) {
11878            final long ident = Binder.clearCallingIdentity();
11879            try {
11880                if (mUserController.shouldConfirmCredentials(userId)) {
11881                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11882                    if (!mKeyguardController.isKeyguardLocked()) {
11883                        // If the device is not locked, we will prompt for credentials immediately.
11884                        mStackSupervisor.lockAllProfileTasks(userId);
11885                    } else {
11886                        // Showing launcher to avoid user entering credential twice.
11887                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11888                    }
11889                }
11890            } finally {
11891                Binder.restoreCallingIdentity(ident);
11892            }
11893        }
11894    }
11895
11896    @Override
11897    public void startConfirmDeviceCredentialIntent(Intent intent) {
11898        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11899        synchronized (this) {
11900            final long ident = Binder.clearCallingIdentity();
11901            try {
11902                mActivityStarter.startConfirmCredentialIntent(intent);
11903            } finally {
11904                Binder.restoreCallingIdentity(ident);
11905            }
11906        }
11907    }
11908
11909    @Override
11910    public void stopAppSwitches() {
11911        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11912                != PackageManager.PERMISSION_GRANTED) {
11913            throw new SecurityException("viewquires permission "
11914                    + android.Manifest.permission.STOP_APP_SWITCHES);
11915        }
11916
11917        synchronized(this) {
11918            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11919                    + APP_SWITCH_DELAY_TIME;
11920            mDidAppSwitch = false;
11921            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11922            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11923            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11924        }
11925    }
11926
11927    public void resumeAppSwitches() {
11928        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11929                != PackageManager.PERMISSION_GRANTED) {
11930            throw new SecurityException("Requires permission "
11931                    + android.Manifest.permission.STOP_APP_SWITCHES);
11932        }
11933
11934        synchronized(this) {
11935            // Note that we don't execute any pending app switches... we will
11936            // let those wait until either the timeout, or the next start
11937            // activity request.
11938            mAppSwitchesAllowedTime = 0;
11939        }
11940    }
11941
11942    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11943            int callingPid, int callingUid, String name) {
11944        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11945            return true;
11946        }
11947
11948        int perm = checkComponentPermission(
11949                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11950                sourceUid, -1, true);
11951        if (perm == PackageManager.PERMISSION_GRANTED) {
11952            return true;
11953        }
11954
11955        // If the actual IPC caller is different from the logical source, then
11956        // also see if they are allowed to control app switches.
11957        if (callingUid != -1 && callingUid != sourceUid) {
11958            perm = checkComponentPermission(
11959                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11960                    callingUid, -1, true);
11961            if (perm == PackageManager.PERMISSION_GRANTED) {
11962                return true;
11963            }
11964        }
11965
11966        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11967        return false;
11968    }
11969
11970    public void setDebugApp(String packageName, boolean waitForDebugger,
11971            boolean persistent) {
11972        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11973                "setDebugApp()");
11974
11975        long ident = Binder.clearCallingIdentity();
11976        try {
11977            // Note that this is not really thread safe if there are multiple
11978            // callers into it at the same time, but that's not a situation we
11979            // care about.
11980            if (persistent) {
11981                final ContentResolver resolver = mContext.getContentResolver();
11982                Settings.Global.putString(
11983                    resolver, Settings.Global.DEBUG_APP,
11984                    packageName);
11985                Settings.Global.putInt(
11986                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11987                    waitForDebugger ? 1 : 0);
11988            }
11989
11990            synchronized (this) {
11991                if (!persistent) {
11992                    mOrigDebugApp = mDebugApp;
11993                    mOrigWaitForDebugger = mWaitForDebugger;
11994                }
11995                mDebugApp = packageName;
11996                mWaitForDebugger = waitForDebugger;
11997                mDebugTransient = !persistent;
11998                if (packageName != null) {
11999                    forceStopPackageLocked(packageName, -1, false, false, true, true,
12000                            false, UserHandle.USER_ALL, "set debug app");
12001                }
12002            }
12003        } finally {
12004            Binder.restoreCallingIdentity(ident);
12005        }
12006    }
12007
12008    void setTrackAllocationApp(ApplicationInfo app, String processName) {
12009        synchronized (this) {
12010            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12011            if (!isDebuggable) {
12012                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12013                    throw new SecurityException("Process not debuggable: " + app.packageName);
12014                }
12015            }
12016
12017            mTrackAllocationApp = processName;
12018        }
12019    }
12020
12021    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
12022        synchronized (this) {
12023            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12024            if (!isDebuggable) {
12025                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12026                    throw new SecurityException("Process not debuggable: " + app.packageName);
12027                }
12028            }
12029            mProfileApp = processName;
12030            mProfileFile = profilerInfo.profileFile;
12031            if (mProfileFd != null) {
12032                try {
12033                    mProfileFd.close();
12034                } catch (IOException e) {
12035                }
12036                mProfileFd = null;
12037            }
12038            mProfileFd = profilerInfo.profileFd;
12039            mSamplingInterval = profilerInfo.samplingInterval;
12040            mAutoStopProfiler = profilerInfo.autoStopProfiler;
12041            mProfileType = 0;
12042        }
12043    }
12044
12045    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
12046        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12047        if (!isDebuggable) {
12048            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12049                throw new SecurityException("Process not debuggable: " + app.packageName);
12050            }
12051        }
12052        mNativeDebuggingApp = processName;
12053    }
12054
12055    @Override
12056    public void setAlwaysFinish(boolean enabled) {
12057        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
12058                "setAlwaysFinish()");
12059
12060        long ident = Binder.clearCallingIdentity();
12061        try {
12062            Settings.Global.putInt(
12063                    mContext.getContentResolver(),
12064                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
12065
12066            synchronized (this) {
12067                mAlwaysFinishActivities = enabled;
12068            }
12069        } finally {
12070            Binder.restoreCallingIdentity(ident);
12071        }
12072    }
12073
12074    @Override
12075    public void setActivityController(IActivityController controller, boolean imAMonkey) {
12076        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12077                "setActivityController()");
12078        synchronized (this) {
12079            mController = controller;
12080            mControllerIsAMonkey = imAMonkey;
12081            Watchdog.getInstance().setActivityController(controller);
12082        }
12083    }
12084
12085    @Override
12086    public void setUserIsMonkey(boolean userIsMonkey) {
12087        synchronized (this) {
12088            synchronized (mPidsSelfLocked) {
12089                final int callingPid = Binder.getCallingPid();
12090                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
12091                if (precessRecord == null) {
12092                    throw new SecurityException("Unknown process: " + callingPid);
12093                }
12094                if (precessRecord.instrumentationUiAutomationConnection  == null) {
12095                    throw new SecurityException("Only an instrumentation process "
12096                            + "with a UiAutomation can call setUserIsMonkey");
12097                }
12098            }
12099            mUserIsMonkey = userIsMonkey;
12100        }
12101    }
12102
12103    @Override
12104    public boolean isUserAMonkey() {
12105        synchronized (this) {
12106            // If there is a controller also implies the user is a monkey.
12107            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12108        }
12109    }
12110
12111    /**
12112     * @deprecated This method is only used by a few internal components and it will soon be
12113     * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12114     * No new code should be calling it.
12115     */
12116    @Deprecated
12117    public void requestBugReport(int bugreportType) {
12118        String extraOptions = null;
12119        switch (bugreportType) {
12120            case ActivityManager.BUGREPORT_OPTION_FULL:
12121                // Default options.
12122                break;
12123            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12124                extraOptions = "bugreportplus";
12125                break;
12126            case ActivityManager.BUGREPORT_OPTION_REMOTE:
12127                extraOptions = "bugreportremote";
12128                break;
12129            case ActivityManager.BUGREPORT_OPTION_WEAR:
12130                extraOptions = "bugreportwear";
12131                break;
12132            default:
12133                throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12134                        + bugreportType);
12135        }
12136        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12137        if (extraOptions != null) {
12138            SystemProperties.set("dumpstate.options", extraOptions);
12139        }
12140        SystemProperties.set("ctl.start", "bugreport");
12141    }
12142
12143    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12144        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12145    }
12146
12147    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12148        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
12149            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12150        }
12151        return KEY_DISPATCHING_TIMEOUT;
12152    }
12153
12154    @Override
12155    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12156        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12157                != PackageManager.PERMISSION_GRANTED) {
12158            throw new SecurityException("Requires permission "
12159                    + android.Manifest.permission.FILTER_EVENTS);
12160        }
12161        ProcessRecord proc;
12162        long timeout;
12163        synchronized (this) {
12164            synchronized (mPidsSelfLocked) {
12165                proc = mPidsSelfLocked.get(pid);
12166            }
12167            timeout = getInputDispatchingTimeoutLocked(proc);
12168        }
12169
12170        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12171            return -1;
12172        }
12173
12174        return timeout;
12175    }
12176
12177    /**
12178     * Handle input dispatching timeouts.
12179     * Returns whether input dispatching should be aborted or not.
12180     */
12181    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12182            final ActivityRecord activity, final ActivityRecord parent,
12183            final boolean aboveSystem, String reason) {
12184        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12185                != PackageManager.PERMISSION_GRANTED) {
12186            throw new SecurityException("Requires permission "
12187                    + android.Manifest.permission.FILTER_EVENTS);
12188        }
12189
12190        final String annotation;
12191        if (reason == null) {
12192            annotation = "Input dispatching timed out";
12193        } else {
12194            annotation = "Input dispatching timed out (" + reason + ")";
12195        }
12196
12197        if (proc != null) {
12198            synchronized (this) {
12199                if (proc.debugging) {
12200                    return false;
12201                }
12202
12203                if (mDidDexOpt) {
12204                    // Give more time since we were dexopting.
12205                    mDidDexOpt = false;
12206                    return false;
12207                }
12208
12209                if (proc.instrumentationClass != null) {
12210                    Bundle info = new Bundle();
12211                    info.putString("shortMsg", "keyDispatchingTimedOut");
12212                    info.putString("longMsg", annotation);
12213                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12214                    return true;
12215                }
12216            }
12217            mHandler.post(new Runnable() {
12218                @Override
12219                public void run() {
12220                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12221                }
12222            });
12223        }
12224
12225        return true;
12226    }
12227
12228    @Override
12229    public Bundle getAssistContextExtras(int requestType) {
12230        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12231                null, 0, null, true /* focused */, true /* newSessionId */,
12232                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
12233        if (pae == null) {
12234            return null;
12235        }
12236        synchronized (pae) {
12237            while (!pae.haveResult) {
12238                try {
12239                    pae.wait();
12240                } catch (InterruptedException e) {
12241                }
12242            }
12243        }
12244        synchronized (this) {
12245            buildAssistBundleLocked(pae, pae.result);
12246            mPendingAssistExtras.remove(pae);
12247            mUiHandler.removeCallbacks(pae);
12248        }
12249        return pae.extras;
12250    }
12251
12252    @Override
12253    public boolean isAssistDataAllowedOnCurrentActivity() {
12254        int userId;
12255        synchronized (this) {
12256            userId = mUserController.getCurrentUserIdLocked();
12257            ActivityRecord activity = getFocusedStack().topActivity();
12258            if (activity == null) {
12259                return false;
12260            }
12261            userId = activity.userId;
12262        }
12263        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12264                Context.DEVICE_POLICY_SERVICE);
12265        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12266    }
12267
12268    @Override
12269    public boolean showAssistFromActivity(IBinder token, Bundle args) {
12270        long ident = Binder.clearCallingIdentity();
12271        try {
12272            synchronized (this) {
12273                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12274                ActivityRecord top = getFocusedStack().topActivity();
12275                if (top != caller) {
12276                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12277                            + " is not current top " + top);
12278                    return false;
12279                }
12280                if (!top.nowVisible) {
12281                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12282                            + " is not visible");
12283                    return false;
12284                }
12285            }
12286            AssistUtils utils = new AssistUtils(mContext);
12287            return utils.showSessionForActiveService(args,
12288                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
12289        } finally {
12290            Binder.restoreCallingIdentity(ident);
12291        }
12292    }
12293
12294    @Override
12295    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12296            Bundle receiverExtras,
12297            IBinder activityToken, boolean focused, boolean newSessionId) {
12298        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12299                0, activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
12300                PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
12301    }
12302
12303    @Override
12304    public boolean requestAutoFillData(IResultReceiver receiver, Bundle receiverExtras,
12305            int resultCode, IBinder activityToken, int flags) {
12306        final boolean forFill = (flags & View.AUTO_FILL_FLAG_TYPE_FILL) != 0;
12307        final boolean forSave = (flags & View.AUTO_FILL_FLAG_TYPE_SAVE) != 0;
12308        if ((forFill && forSave) || (!forFill) && !(forSave)) {
12309            // There can be only one!
12310            Slog.w(TAG,  "requestAutoFillData(): invalid flags (" + flags + ")");
12311            return false;
12312        }
12313
12314        // NOTE: we could always use ActivityManager.ASSIST_CONTEXT_FULL and let ActivityThread
12315        // rely on the flags to decide whether the handleRequestAssistContextExtras() is for
12316        // auto-fill, but it's safer to explicitly use new AutoFill types, in case the Assist
12317        // requests use flags in the future as well (since their flags value might collide with the
12318        // auto-fill flag values).
12319        final int type = forFill?
12320                ActivityManager.ASSIST_CONTEXT_AUTO_FILL :
12321                    ActivityManager.ASSIST_CONTEXT_AUTO_FILL_SAVE;
12322
12323        return enqueueAssistContext(type, null, null, receiver, receiverExtras, resultCode,
12324                activityToken, true, true, UserHandle.getCallingUserId(), null,
12325                PENDING_AUTO_FILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
12326    }
12327
12328    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12329            IResultReceiver receiver, Bundle receiverExtras, int resultCode, IBinder activityToken,
12330            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
12331            int flags) {
12332        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12333                "enqueueAssistContext()");
12334        synchronized (this) {
12335            ActivityRecord activity = getFocusedStack().topActivity();
12336            if (activity == null) {
12337                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12338                return null;
12339            }
12340            if (activity.app == null || activity.app.thread == null) {
12341                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12342                return null;
12343            }
12344            if (focused) {
12345                if (activityToken != null) {
12346                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12347                    if (activity != caller) {
12348                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12349                                + " is not current top " + activity);
12350                        return null;
12351                    }
12352                }
12353            } else {
12354                activity = ActivityRecord.forTokenLocked(activityToken);
12355                if (activity == null) {
12356                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12357                            + " couldn't be found");
12358                    return null;
12359                }
12360            }
12361
12362            PendingAssistExtras pae;
12363            Bundle extras = new Bundle();
12364            if (args != null) {
12365                extras.putAll(args);
12366            }
12367            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12368            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12369            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12370                    resultCode, userHandle, flags);
12371            // Increment the sessionId if necessary
12372            if (newSessionId) {
12373                mViSessionId++;
12374            }
12375            try {
12376                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12377                        requestType, mViSessionId, flags);
12378                mPendingAssistExtras.add(pae);
12379                mUiHandler.postDelayed(pae, timeout);
12380            } catch (RemoteException e) {
12381                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12382                return null;
12383            }
12384            return pae;
12385        }
12386    }
12387
12388    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12389        IResultReceiver receiver;
12390        synchronized (this) {
12391            mPendingAssistExtras.remove(pae);
12392            receiver = pae.receiver;
12393        }
12394        if (receiver != null) {
12395            // Caller wants result sent back to them.
12396            Bundle sendBundle = new Bundle();
12397            // At least return the receiver extras
12398            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12399                    pae.receiverExtras);
12400            try {
12401                pae.receiver.send(0, sendBundle);
12402            } catch (RemoteException e) {
12403            }
12404        }
12405    }
12406
12407    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12408        if (result != null) {
12409            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12410        }
12411        if (pae.hint != null) {
12412            pae.extras.putBoolean(pae.hint, true);
12413        }
12414    }
12415
12416    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12417            AssistContent content, Uri referrer) {
12418        PendingAssistExtras pae = (PendingAssistExtras)token;
12419        synchronized (pae) {
12420            pae.result = extras;
12421            pae.structure = structure;
12422            pae.content = content;
12423            if (referrer != null) {
12424                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12425            }
12426            pae.haveResult = true;
12427            pae.notifyAll();
12428            if (pae.intent == null && pae.receiver == null) {
12429                // Caller is just waiting for the result.
12430                return;
12431            }
12432        }
12433
12434        // We are now ready to launch the assist activity.
12435        IResultReceiver sendReceiver = null;
12436        Bundle sendBundle = null;
12437        synchronized (this) {
12438            buildAssistBundleLocked(pae, extras);
12439            boolean exists = mPendingAssistExtras.remove(pae);
12440            mUiHandler.removeCallbacks(pae);
12441            if (!exists) {
12442                // Timed out.
12443                return;
12444            }
12445            if ((sendReceiver=pae.receiver) != null) {
12446                // Caller wants result sent back to them.
12447                sendBundle = new Bundle();
12448                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12449                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12450                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12451                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12452                        pae.receiverExtras);
12453                if (pae.flags > 0) {
12454                    sendBundle.putInt(VoiceInteractionSession.KEY_FLAGS, pae.flags);
12455                }
12456                IBinder cb = extras.getBinder(AutoFillService.KEY_CALLBACK);
12457                if (cb != null) {
12458                    sendBundle.putBinder(AutoFillService.KEY_CALLBACK, cb);
12459                }
12460            }
12461        }
12462        if (sendReceiver != null) {
12463            try {
12464                sendReceiver.send(pae.resultCode, sendBundle);
12465            } catch (RemoteException e) {
12466            }
12467            return;
12468        }
12469
12470        long ident = Binder.clearCallingIdentity();
12471        try {
12472            pae.intent.replaceExtras(pae.extras);
12473            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12474                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12475                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12476            closeSystemDialogs("assist");
12477            try {
12478                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12479            } catch (ActivityNotFoundException e) {
12480                Slog.w(TAG, "No activity to handle assist action.", e);
12481            }
12482        } finally {
12483            Binder.restoreCallingIdentity(ident);
12484        }
12485    }
12486
12487    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12488            Bundle args) {
12489        return enqueueAssistContext(requestType, intent, hint, null, null, 0, null,
12490                true /* focused */, true /* newSessionId */, userHandle, args,
12491                PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
12492    }
12493
12494    public void registerProcessObserver(IProcessObserver observer) {
12495        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12496                "registerProcessObserver()");
12497        synchronized (this) {
12498            mProcessObservers.register(observer);
12499        }
12500    }
12501
12502    @Override
12503    public void unregisterProcessObserver(IProcessObserver observer) {
12504        synchronized (this) {
12505            mProcessObservers.unregister(observer);
12506        }
12507    }
12508
12509    @Override
12510    public void registerUidObserver(IUidObserver observer, int which, int cutpoint,
12511            String callingPackage) {
12512        if (!hasUsageStatsPermission(callingPackage)) {
12513            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
12514                    "registerUidObserver");
12515        }
12516        synchronized (this) {
12517            mUidObservers.register(observer, new UidObserverRegistration(Binder.getCallingUid(),
12518                    callingPackage, which, cutpoint));
12519        }
12520    }
12521
12522    @Override
12523    public void unregisterUidObserver(IUidObserver observer) {
12524        synchronized (this) {
12525            mUidObservers.unregister(observer);
12526        }
12527    }
12528
12529    @Override
12530    public boolean convertFromTranslucent(IBinder token) {
12531        final long origId = Binder.clearCallingIdentity();
12532        try {
12533            synchronized (this) {
12534                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12535                if (r == null) {
12536                    return false;
12537                }
12538                final boolean translucentChanged = r.changeWindowTranslucency(true);
12539                if (translucentChanged) {
12540                    r.getStack().releaseBackgroundResources(r);
12541                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12542                }
12543                mWindowManager.setAppFullscreen(token, true);
12544                return translucentChanged;
12545            }
12546        } finally {
12547            Binder.restoreCallingIdentity(origId);
12548        }
12549    }
12550
12551    @Override
12552    public boolean convertToTranslucent(IBinder token, Bundle options) {
12553        final long origId = Binder.clearCallingIdentity();
12554        try {
12555            synchronized (this) {
12556                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12557                if (r == null) {
12558                    return false;
12559                }
12560                int index = r.task.mActivities.lastIndexOf(r);
12561                if (index > 0) {
12562                    ActivityRecord under = r.task.mActivities.get(index - 1);
12563                    under.returningOptions = ActivityOptions.fromBundle(options);
12564                }
12565                final boolean translucentChanged = r.changeWindowTranslucency(false);
12566                if (translucentChanged) {
12567                    r.getStack().convertActivityToTranslucent(r);
12568                }
12569                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12570                mWindowManager.setAppFullscreen(token, false);
12571                return translucentChanged;
12572            }
12573        } finally {
12574            Binder.restoreCallingIdentity(origId);
12575        }
12576    }
12577
12578    @Override
12579    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12580        final long origId = Binder.clearCallingIdentity();
12581        try {
12582            synchronized (this) {
12583                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12584                if (r != null) {
12585                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12586                }
12587            }
12588            return false;
12589        } finally {
12590            Binder.restoreCallingIdentity(origId);
12591        }
12592    }
12593
12594    @Override
12595    public boolean isBackgroundVisibleBehind(IBinder token) {
12596        final long origId = Binder.clearCallingIdentity();
12597        try {
12598            synchronized (this) {
12599                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12600                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12601                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12602                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12603                return visible;
12604            }
12605        } finally {
12606            Binder.restoreCallingIdentity(origId);
12607        }
12608    }
12609
12610    @Override
12611    public Bundle getActivityOptions(IBinder token) {
12612        final long origId = Binder.clearCallingIdentity();
12613        try {
12614            synchronized (this) {
12615                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12616                if (r != null) {
12617                    final ActivityOptions activityOptions = r.pendingOptions;
12618                    r.pendingOptions = null;
12619                    return activityOptions == null ? null : activityOptions.toBundle();
12620                }
12621                return null;
12622            }
12623        } finally {
12624            Binder.restoreCallingIdentity(origId);
12625        }
12626    }
12627
12628    @Override
12629    public void setImmersive(IBinder token, boolean immersive) {
12630        synchronized(this) {
12631            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12632            if (r == null) {
12633                throw new IllegalArgumentException();
12634            }
12635            r.immersive = immersive;
12636
12637            // update associated state if we're frontmost
12638            if (r == mStackSupervisor.getResumedActivityLocked()) {
12639                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12640                applyUpdateLockStateLocked(r);
12641            }
12642        }
12643    }
12644
12645    @Override
12646    public boolean isImmersive(IBinder token) {
12647        synchronized (this) {
12648            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12649            if (r == null) {
12650                throw new IllegalArgumentException();
12651            }
12652            return r.immersive;
12653        }
12654    }
12655
12656    public void setVrThread(int tid) {
12657        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12658            throw new UnsupportedOperationException("VR mode not supported on this device!");
12659        }
12660
12661        synchronized (this) {
12662            ProcessRecord proc;
12663            synchronized (mPidsSelfLocked) {
12664                final int pid = Binder.getCallingPid();
12665                proc = mPidsSelfLocked.get(pid);
12666
12667                if (proc != null && mInVrMode && tid >= 0) {
12668                    // ensure the tid belongs to the process
12669                    if (!Process.isThreadInProcess(pid, tid)) {
12670                        throw new IllegalArgumentException("VR thread does not belong to process");
12671                    }
12672
12673                    // reset existing VR thread to CFS if this thread still exists and belongs to
12674                    // the calling process
12675                    if (proc.vrThreadTid != 0
12676                            && Process.isThreadInProcess(pid, proc.vrThreadTid)) {
12677                        try {
12678                            Process.setThreadScheduler(proc.vrThreadTid, Process.SCHED_OTHER, 0);
12679                        } catch (IllegalArgumentException e) {
12680                            // Ignore this.  Only occurs in race condition where previous VR thread
12681                            // was destroyed during this method call.
12682                        }
12683                    }
12684
12685                    proc.vrThreadTid = tid;
12686
12687                    // promote to FIFO now if the tid is non-zero
12688                    try {
12689                        if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
12690                            proc.vrThreadTid > 0) {
12691                            Process.setThreadScheduler(proc.vrThreadTid,
12692                                Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12693                        }
12694                    } catch (IllegalArgumentException e) {
12695                        Slog.e(TAG, "Failed to set scheduling policy, thread does"
12696                               + " not exist:\n" + e);
12697                    }
12698                }
12699            }
12700        }
12701    }
12702
12703    @Override
12704    public void setRenderThread(int tid) {
12705        synchronized (this) {
12706            ProcessRecord proc;
12707            synchronized (mPidsSelfLocked) {
12708                int pid = Binder.getCallingPid();
12709                proc = mPidsSelfLocked.get(pid);
12710                if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
12711                    // ensure the tid belongs to the process
12712                    if (!Process.isThreadInProcess(pid, tid)) {
12713                        throw new IllegalArgumentException(
12714                            "Render thread does not belong to process");
12715                    }
12716                    proc.renderThreadTid = tid;
12717                    if (DEBUG_OOM_ADJ) {
12718                        Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
12719                    }
12720                    // promote to FIFO now
12721                    if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
12722                        if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
12723                        if (mUseFifoUiScheduling) {
12724                            Process.setThreadScheduler(proc.renderThreadTid,
12725                                Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12726                        } else {
12727                            Process.setThreadPriority(proc.renderThreadTid, -10);
12728                        }
12729                    }
12730                } else {
12731                    if (DEBUG_OOM_ADJ) {
12732                        Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
12733                               "PID: " + pid + ", TID: " + tid + " FIFO: " +
12734                               mUseFifoUiScheduling);
12735                    }
12736                }
12737            }
12738        }
12739    }
12740
12741    @Override
12742    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12743        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12744            throw new UnsupportedOperationException("VR mode not supported on this device!");
12745        }
12746
12747        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12748
12749        ActivityRecord r;
12750        synchronized (this) {
12751            r = ActivityRecord.isInStackLocked(token);
12752        }
12753
12754        if (r == null) {
12755            throw new IllegalArgumentException();
12756        }
12757
12758        int err;
12759        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12760                VrManagerInternal.NO_ERROR) {
12761            return err;
12762        }
12763
12764        synchronized(this) {
12765            r.requestedVrComponent = (enabled) ? packageName : null;
12766
12767            // Update associated state if this activity is currently focused
12768            if (r == mStackSupervisor.getResumedActivityLocked()) {
12769                applyUpdateVrModeLocked(r);
12770            }
12771            return 0;
12772        }
12773    }
12774
12775    @Override
12776    public boolean isVrModePackageEnabled(ComponentName packageName) {
12777        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12778            throw new UnsupportedOperationException("VR mode not supported on this device!");
12779        }
12780
12781        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12782
12783        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12784                VrManagerInternal.NO_ERROR;
12785    }
12786
12787    public boolean isTopActivityImmersive() {
12788        enforceNotIsolatedCaller("startActivity");
12789        synchronized (this) {
12790            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12791            return (r != null) ? r.immersive : false;
12792        }
12793    }
12794
12795    @Override
12796    public boolean isTopOfTask(IBinder token) {
12797        synchronized (this) {
12798            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12799            if (r == null) {
12800                throw new IllegalArgumentException();
12801            }
12802            return r.task.getTopActivity() == r;
12803        }
12804    }
12805
12806    @Override
12807    public void setHasTopUi(boolean hasTopUi) throws RemoteException {
12808        if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
12809            String msg = "Permission Denial: setHasTopUi() from pid="
12810                    + Binder.getCallingPid()
12811                    + ", uid=" + Binder.getCallingUid()
12812                    + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
12813            Slog.w(TAG, msg);
12814            throw new SecurityException(msg);
12815        }
12816        final int pid = Binder.getCallingPid();
12817        final long origId = Binder.clearCallingIdentity();
12818        try {
12819            synchronized (this) {
12820                boolean changed = false;
12821                ProcessRecord pr;
12822                synchronized (mPidsSelfLocked) {
12823                    pr = mPidsSelfLocked.get(pid);
12824                    if (pr == null) {
12825                        Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
12826                        return;
12827                    }
12828                    if (pr.hasTopUi != hasTopUi) {
12829                        Slog.i(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
12830                        pr.hasTopUi = hasTopUi;
12831                        changed = true;
12832                    }
12833                }
12834                if (changed) {
12835                    updateOomAdjLocked(pr);
12836                }
12837            }
12838        } finally {
12839            Binder.restoreCallingIdentity(origId);
12840        }
12841    }
12842
12843    public final void enterSafeMode() {
12844        synchronized(this) {
12845            // It only makes sense to do this before the system is ready
12846            // and started launching other packages.
12847            if (!mSystemReady) {
12848                try {
12849                    AppGlobals.getPackageManager().enterSafeMode();
12850                } catch (RemoteException e) {
12851                }
12852            }
12853
12854            mSafeMode = true;
12855        }
12856    }
12857
12858    public final void showSafeModeOverlay() {
12859        View v = LayoutInflater.from(mContext).inflate(
12860                com.android.internal.R.layout.safe_mode, null);
12861        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12862        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12863        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12864        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12865        lp.gravity = Gravity.BOTTOM | Gravity.START;
12866        lp.format = v.getBackground().getOpacity();
12867        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12868                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12869        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12870        ((WindowManager)mContext.getSystemService(
12871                Context.WINDOW_SERVICE)).addView(v, lp);
12872    }
12873
12874    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12875        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12876            return;
12877        }
12878        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12879        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12880        synchronized (stats) {
12881            if (mBatteryStatsService.isOnBattery()) {
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                BatteryStatsImpl.Uid.Pkg pkg =
12891                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12892                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12893                pkg.noteWakeupAlarmLocked(tag);
12894            }
12895        }
12896    }
12897
12898    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12899        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12900            return;
12901        }
12902        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12903        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12904        synchronized (stats) {
12905            mBatteryStatsService.enforceCallingPermission();
12906            int MY_UID = Binder.getCallingUid();
12907            final int uid;
12908            if (sender == null) {
12909                uid = sourceUid;
12910            } else {
12911                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12912            }
12913            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12914        }
12915    }
12916
12917    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12918        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12919            return;
12920        }
12921        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12922        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12923        synchronized (stats) {
12924            mBatteryStatsService.enforceCallingPermission();
12925            int MY_UID = Binder.getCallingUid();
12926            final int uid;
12927            if (sender == null) {
12928                uid = sourceUid;
12929            } else {
12930                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12931            }
12932            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12933        }
12934    }
12935
12936    public boolean killPids(int[] pids, String pReason, boolean secure) {
12937        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12938            throw new SecurityException("killPids only available to the system");
12939        }
12940        String reason = (pReason == null) ? "Unknown" : pReason;
12941        // XXX Note: don't acquire main activity lock here, because the window
12942        // manager calls in with its locks held.
12943
12944        boolean killed = false;
12945        synchronized (mPidsSelfLocked) {
12946            int worstType = 0;
12947            for (int i=0; i<pids.length; i++) {
12948                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12949                if (proc != null) {
12950                    int type = proc.setAdj;
12951                    if (type > worstType) {
12952                        worstType = type;
12953                    }
12954                }
12955            }
12956
12957            // If the worst oom_adj is somewhere in the cached proc LRU range,
12958            // then constrain it so we will kill all cached procs.
12959            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12960                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12961                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12962            }
12963
12964            // If this is not a secure call, don't let it kill processes that
12965            // are important.
12966            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12967                worstType = ProcessList.SERVICE_ADJ;
12968            }
12969
12970            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12971            for (int i=0; i<pids.length; i++) {
12972                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12973                if (proc == null) {
12974                    continue;
12975                }
12976                int adj = proc.setAdj;
12977                if (adj >= worstType && !proc.killedByAm) {
12978                    proc.kill(reason, true);
12979                    killed = true;
12980                }
12981            }
12982        }
12983        return killed;
12984    }
12985
12986    @Override
12987    public void killUid(int appId, int userId, String reason) {
12988        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12989        synchronized (this) {
12990            final long identity = Binder.clearCallingIdentity();
12991            try {
12992                killPackageProcessesLocked(null, appId, userId,
12993                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12994                        reason != null ? reason : "kill uid");
12995            } finally {
12996                Binder.restoreCallingIdentity(identity);
12997            }
12998        }
12999    }
13000
13001    @Override
13002    public boolean killProcessesBelowForeground(String reason) {
13003        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
13004            throw new SecurityException("killProcessesBelowForeground() only available to system");
13005        }
13006
13007        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
13008    }
13009
13010    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
13011        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
13012            throw new SecurityException("killProcessesBelowAdj() only available to system");
13013        }
13014
13015        boolean killed = false;
13016        synchronized (mPidsSelfLocked) {
13017            final int size = mPidsSelfLocked.size();
13018            for (int i = 0; i < size; i++) {
13019                final int pid = mPidsSelfLocked.keyAt(i);
13020                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13021                if (proc == null) continue;
13022
13023                final int adj = proc.setAdj;
13024                if (adj > belowAdj && !proc.killedByAm) {
13025                    proc.kill(reason, true);
13026                    killed = true;
13027                }
13028            }
13029        }
13030        return killed;
13031    }
13032
13033    @Override
13034    public void hang(final IBinder who, boolean allowRestart) {
13035        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13036                != PackageManager.PERMISSION_GRANTED) {
13037            throw new SecurityException("Requires permission "
13038                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13039        }
13040
13041        final IBinder.DeathRecipient death = new DeathRecipient() {
13042            @Override
13043            public void binderDied() {
13044                synchronized (this) {
13045                    notifyAll();
13046                }
13047            }
13048        };
13049
13050        try {
13051            who.linkToDeath(death, 0);
13052        } catch (RemoteException e) {
13053            Slog.w(TAG, "hang: given caller IBinder is already dead.");
13054            return;
13055        }
13056
13057        synchronized (this) {
13058            Watchdog.getInstance().setAllowRestart(allowRestart);
13059            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
13060            synchronized (death) {
13061                while (who.isBinderAlive()) {
13062                    try {
13063                        death.wait();
13064                    } catch (InterruptedException e) {
13065                    }
13066                }
13067            }
13068            Watchdog.getInstance().setAllowRestart(true);
13069        }
13070    }
13071
13072    @Override
13073    public void restart() {
13074        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13075                != PackageManager.PERMISSION_GRANTED) {
13076            throw new SecurityException("Requires permission "
13077                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13078        }
13079
13080        Log.i(TAG, "Sending shutdown broadcast...");
13081
13082        BroadcastReceiver br = new BroadcastReceiver() {
13083            @Override public void onReceive(Context context, Intent intent) {
13084                // Now the broadcast is done, finish up the low-level shutdown.
13085                Log.i(TAG, "Shutting down activity manager...");
13086                shutdown(10000);
13087                Log.i(TAG, "Shutdown complete, restarting!");
13088                Process.killProcess(Process.myPid());
13089                System.exit(10);
13090            }
13091        };
13092
13093        // First send the high-level shut down broadcast.
13094        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
13095        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
13096        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
13097        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
13098        mContext.sendOrderedBroadcastAsUser(intent,
13099                UserHandle.ALL, null, br, mHandler, 0, null, null);
13100        */
13101        br.onReceive(mContext, intent);
13102    }
13103
13104    private long getLowRamTimeSinceIdle(long now) {
13105        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
13106    }
13107
13108    @Override
13109    public void performIdleMaintenance() {
13110        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13111                != PackageManager.PERMISSION_GRANTED) {
13112            throw new SecurityException("Requires permission "
13113                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13114        }
13115
13116        synchronized (this) {
13117            final long now = SystemClock.uptimeMillis();
13118            final long timeSinceLastIdle = now - mLastIdleTime;
13119            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
13120            mLastIdleTime = now;
13121            mLowRamTimeSinceLastIdle = 0;
13122            if (mLowRamStartTime != 0) {
13123                mLowRamStartTime = now;
13124            }
13125
13126            StringBuilder sb = new StringBuilder(128);
13127            sb.append("Idle maintenance over ");
13128            TimeUtils.formatDuration(timeSinceLastIdle, sb);
13129            sb.append(" low RAM for ");
13130            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13131            Slog.i(TAG, sb.toString());
13132
13133            // If at least 1/3 of our time since the last idle period has been spent
13134            // with RAM low, then we want to kill processes.
13135            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
13136
13137            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13138                ProcessRecord proc = mLruProcesses.get(i);
13139                if (proc.notCachedSinceIdle) {
13140                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
13141                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
13142                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
13143                        if (doKilling && proc.initialIdlePss != 0
13144                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
13145                            sb = new StringBuilder(128);
13146                            sb.append("Kill");
13147                            sb.append(proc.processName);
13148                            sb.append(" in idle maint: pss=");
13149                            sb.append(proc.lastPss);
13150                            sb.append(", swapPss=");
13151                            sb.append(proc.lastSwapPss);
13152                            sb.append(", initialPss=");
13153                            sb.append(proc.initialIdlePss);
13154                            sb.append(", period=");
13155                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
13156                            sb.append(", lowRamPeriod=");
13157                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13158                            Slog.wtfQuiet(TAG, sb.toString());
13159                            proc.kill("idle maint (pss " + proc.lastPss
13160                                    + " from " + proc.initialIdlePss + ")", true);
13161                        }
13162                    }
13163                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
13164                        && proc.setProcState >= ActivityManager.PROCESS_STATE_PERSISTENT) {
13165                    proc.notCachedSinceIdle = true;
13166                    proc.initialIdlePss = 0;
13167                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
13168                            mTestPssMode, isSleepingLocked(), now);
13169                }
13170            }
13171
13172            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
13173            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
13174        }
13175    }
13176
13177    @Override
13178    public void sendIdleJobTrigger() {
13179        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13180                != PackageManager.PERMISSION_GRANTED) {
13181            throw new SecurityException("Requires permission "
13182                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13183        }
13184
13185        final long ident = Binder.clearCallingIdentity();
13186        try {
13187            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
13188                    .setPackage("android")
13189                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13190            broadcastIntent(null, intent, null, null, 0, null, null, null,
13191                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
13192        } finally {
13193            Binder.restoreCallingIdentity(ident);
13194        }
13195    }
13196
13197    private void retrieveSettings() {
13198        final ContentResolver resolver = mContext.getContentResolver();
13199        final boolean freeformWindowManagement =
13200                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
13201                        || Settings.Global.getInt(
13202                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
13203        final boolean supportsPictureInPicture =
13204                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
13205
13206        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
13207        final boolean supportsSplitScreenMultiWindow =
13208                ActivityManager.supportsSplitScreenMultiWindow();
13209        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
13210        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
13211        final boolean alwaysFinishActivities =
13212                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
13213        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
13214        final boolean forceResizable = Settings.Global.getInt(
13215                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
13216        final boolean supportsLeanbackOnly =
13217                mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
13218
13219        // Transfer any global setting for forcing RTL layout, into a System Property
13220        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
13221
13222        final Configuration configuration = new Configuration();
13223        Settings.System.getConfiguration(resolver, configuration);
13224        if (forceRtl) {
13225            // This will take care of setting the correct layout direction flags
13226            configuration.setLayoutDirection(configuration.locale);
13227        }
13228
13229        synchronized (this) {
13230            mDebugApp = mOrigDebugApp = debugApp;
13231            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
13232            mAlwaysFinishActivities = alwaysFinishActivities;
13233            mSupportsLeanbackOnly = supportsLeanbackOnly;
13234            mForceResizableActivities = forceResizable;
13235            if (supportsMultiWindow || forceResizable) {
13236                mSupportsMultiWindow = true;
13237                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
13238                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
13239            } else {
13240                mSupportsMultiWindow = false;
13241                mSupportsFreeformWindowManagement = false;
13242                mSupportsPictureInPicture = false;
13243            }
13244            mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
13245            mWindowManager.setForceResizableTasks(mForceResizableActivities);
13246            mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
13247            // This happens before any activities are started, so we can change global configuration
13248            // in-place.
13249            updateConfigurationLocked(configuration, null, true);
13250            final Configuration globalConfig = getGlobalConfiguration();
13251            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
13252
13253            // Load resources only after the current configuration has been set.
13254            final Resources res = mContext.getResources();
13255            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
13256            mThumbnailWidth = res.getDimensionPixelSize(
13257                    com.android.internal.R.dimen.thumbnail_width);
13258            mThumbnailHeight = res.getDimensionPixelSize(
13259                    com.android.internal.R.dimen.thumbnail_height);
13260            mMinPipAspectRatio = res.getFloat(
13261                    com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
13262            mMaxPipAspectRatio = res.getFloat(
13263                    com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
13264            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
13265                    com.android.internal.R.string.config_appsNotReportingCrashes));
13266            mUserController.mUserSwitchUiEnabled = !res.getBoolean(
13267                    com.android.internal.R.bool.config_customUserSwitchUi);
13268            if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
13269                mFullscreenThumbnailScale = (float) res
13270                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
13271                    (float) globalConfig.screenWidthDp;
13272            } else {
13273                mFullscreenThumbnailScale = res.getFraction(
13274                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
13275            }
13276        }
13277    }
13278
13279    public void systemReady(final Runnable goingCallback, BootTimingsTraceLog traceLog) {
13280        traceLog.traceBegin("PhaseActivityManagerReady");
13281        synchronized(this) {
13282            if (mSystemReady) {
13283                // If we're done calling all the receivers, run the next "boot phase" passed in
13284                // by the SystemServer
13285                if (goingCallback != null) {
13286                    goingCallback.run();
13287                }
13288                return;
13289            }
13290
13291            mLocalDeviceIdleController
13292                    = LocalServices.getService(DeviceIdleController.LocalService.class);
13293
13294            // Make sure we have the current profile info, since it is needed for security checks.
13295            mUserController.onSystemReady();
13296            mRecentTasks.onSystemReadyLocked();
13297            mAppOpsService.systemReady();
13298            mSystemReady = true;
13299        }
13300
13301        ArrayList<ProcessRecord> procsToKill = null;
13302        synchronized(mPidsSelfLocked) {
13303            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
13304                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13305                if (!isAllowedWhileBooting(proc.info)){
13306                    if (procsToKill == null) {
13307                        procsToKill = new ArrayList<ProcessRecord>();
13308                    }
13309                    procsToKill.add(proc);
13310                }
13311            }
13312        }
13313
13314        synchronized(this) {
13315            if (procsToKill != null) {
13316                for (int i=procsToKill.size()-1; i>=0; i--) {
13317                    ProcessRecord proc = procsToKill.get(i);
13318                    Slog.i(TAG, "Removing system update proc: " + proc);
13319                    removeProcessLocked(proc, true, false, "system update done");
13320                }
13321            }
13322
13323            // Now that we have cleaned up any update processes, we
13324            // are ready to start launching real processes and know that
13325            // we won't trample on them any more.
13326            mProcessesReady = true;
13327        }
13328
13329        Slog.i(TAG, "System now ready");
13330        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
13331            SystemClock.uptimeMillis());
13332
13333        synchronized(this) {
13334            // Make sure we have no pre-ready processes sitting around.
13335
13336            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
13337                ResolveInfo ri = mContext.getPackageManager()
13338                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
13339                                STOCK_PM_FLAGS);
13340                CharSequence errorMsg = null;
13341                if (ri != null) {
13342                    ActivityInfo ai = ri.activityInfo;
13343                    ApplicationInfo app = ai.applicationInfo;
13344                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
13345                        mTopAction = Intent.ACTION_FACTORY_TEST;
13346                        mTopData = null;
13347                        mTopComponent = new ComponentName(app.packageName,
13348                                ai.name);
13349                    } else {
13350                        errorMsg = mContext.getResources().getText(
13351                                com.android.internal.R.string.factorytest_not_system);
13352                    }
13353                } else {
13354                    errorMsg = mContext.getResources().getText(
13355                            com.android.internal.R.string.factorytest_no_action);
13356                }
13357                if (errorMsg != null) {
13358                    mTopAction = null;
13359                    mTopData = null;
13360                    mTopComponent = null;
13361                    Message msg = Message.obtain();
13362                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
13363                    msg.getData().putCharSequence("msg", errorMsg);
13364                    mUiHandler.sendMessage(msg);
13365                }
13366            }
13367        }
13368
13369        retrieveSettings();
13370        final int currentUserId;
13371        synchronized (this) {
13372            currentUserId = mUserController.getCurrentUserIdLocked();
13373            readGrantedUriPermissionsLocked();
13374        }
13375
13376        if (goingCallback != null) goingCallback.run();
13377        traceLog.traceBegin("ActivityManagerStartApps");
13378        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
13379                Integer.toString(currentUserId), currentUserId);
13380        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
13381                Integer.toString(currentUserId), currentUserId);
13382        mSystemServiceManager.startUser(currentUserId);
13383
13384        synchronized (this) {
13385            // Only start up encryption-aware persistent apps; once user is
13386            // unlocked we'll come back around and start unaware apps
13387            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
13388
13389            // Start up initial activity.
13390            mBooting = true;
13391            // Enable home activity for system user, so that the system can always boot. We don't
13392            // do this when the system user is not setup since the setup wizard should be the one
13393            // to handle home activity in this case.
13394            if (UserManager.isSplitSystemUser() &&
13395                    Settings.Secure.getInt(mContext.getContentResolver(),
13396                         Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
13397                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
13398                try {
13399                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
13400                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
13401                            UserHandle.USER_SYSTEM);
13402                } catch (RemoteException e) {
13403                    throw e.rethrowAsRuntimeException();
13404                }
13405            }
13406            startHomeActivityLocked(currentUserId, "systemReady");
13407
13408            try {
13409                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
13410                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
13411                            + " data partition or your device will be unstable.");
13412                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
13413                }
13414            } catch (RemoteException e) {
13415            }
13416
13417            if (!Build.isBuildConsistent()) {
13418                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
13419                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
13420            }
13421
13422            long ident = Binder.clearCallingIdentity();
13423            try {
13424                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
13425                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13426                        | Intent.FLAG_RECEIVER_FOREGROUND);
13427                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13428                broadcastIntentLocked(null, null, intent,
13429                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
13430                        null, false, false, MY_PID, Process.SYSTEM_UID,
13431                        currentUserId);
13432                intent = new Intent(Intent.ACTION_USER_STARTING);
13433                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13434                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13435                broadcastIntentLocked(null, null, intent,
13436                        null, new IIntentReceiver.Stub() {
13437                            @Override
13438                            public void performReceive(Intent intent, int resultCode, String data,
13439                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13440                                    throws RemoteException {
13441                            }
13442                        }, 0, null, null,
13443                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13444                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13445            } catch (Throwable t) {
13446                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13447            } finally {
13448                Binder.restoreCallingIdentity(ident);
13449            }
13450            mStackSupervisor.resumeFocusedStackTopActivityLocked();
13451            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13452            traceLog.traceEnd(); // ActivityManagerStartApps
13453            traceLog.traceEnd(); // PhaseActivityManagerReady
13454        }
13455    }
13456
13457    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13458        synchronized (this) {
13459            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13460        }
13461    }
13462
13463    void skipCurrentReceiverLocked(ProcessRecord app) {
13464        for (BroadcastQueue queue : mBroadcastQueues) {
13465            queue.skipCurrentReceiverLocked(app);
13466        }
13467    }
13468
13469    /**
13470     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13471     * The application process will exit immediately after this call returns.
13472     * @param app object of the crashing app, null for the system server
13473     * @param crashInfo describing the exception
13474     */
13475    public void handleApplicationCrash(IBinder app,
13476            ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
13477        ProcessRecord r = findAppProcess(app, "Crash");
13478        final String processName = app == null ? "system_server"
13479                : (r == null ? "unknown" : r.processName);
13480
13481        handleApplicationCrashInner("crash", r, processName, crashInfo);
13482    }
13483
13484    /* Native crash reporting uses this inner version because it needs to be somewhat
13485     * decoupled from the AM-managed cleanup lifecycle
13486     */
13487    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13488            ApplicationErrorReport.CrashInfo crashInfo) {
13489        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13490                UserHandle.getUserId(Binder.getCallingUid()), processName,
13491                r == null ? -1 : r.info.flags,
13492                crashInfo.exceptionClassName,
13493                crashInfo.exceptionMessage,
13494                crashInfo.throwFileName,
13495                crashInfo.throwLineNumber);
13496
13497        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13498
13499        mAppErrors.crashApplication(r, crashInfo);
13500    }
13501
13502    public void handleApplicationStrictModeViolation(
13503            IBinder app,
13504            int violationMask,
13505            StrictMode.ViolationInfo info) {
13506        ProcessRecord r = findAppProcess(app, "StrictMode");
13507        if (r == null) {
13508            return;
13509        }
13510
13511        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13512            Integer stackFingerprint = info.hashCode();
13513            boolean logIt = true;
13514            synchronized (mAlreadyLoggedViolatedStacks) {
13515                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13516                    logIt = false;
13517                    // TODO: sub-sample into EventLog for these, with
13518                    // the info.durationMillis?  Then we'd get
13519                    // the relative pain numbers, without logging all
13520                    // the stack traces repeatedly.  We'd want to do
13521                    // likewise in the client code, which also does
13522                    // dup suppression, before the Binder call.
13523                } else {
13524                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13525                        mAlreadyLoggedViolatedStacks.clear();
13526                    }
13527                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13528                }
13529            }
13530            if (logIt) {
13531                logStrictModeViolationToDropBox(r, info);
13532            }
13533        }
13534
13535        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13536            AppErrorResult result = new AppErrorResult();
13537            synchronized (this) {
13538                final long origId = Binder.clearCallingIdentity();
13539
13540                Message msg = Message.obtain();
13541                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13542                HashMap<String, Object> data = new HashMap<String, Object>();
13543                data.put("result", result);
13544                data.put("app", r);
13545                data.put("violationMask", violationMask);
13546                data.put("info", info);
13547                msg.obj = data;
13548                mUiHandler.sendMessage(msg);
13549
13550                Binder.restoreCallingIdentity(origId);
13551            }
13552            int res = result.get();
13553            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13554        }
13555    }
13556
13557    // Depending on the policy in effect, there could be a bunch of
13558    // these in quick succession so we try to batch these together to
13559    // minimize disk writes, number of dropbox entries, and maximize
13560    // compression, by having more fewer, larger records.
13561    private void logStrictModeViolationToDropBox(
13562            ProcessRecord process,
13563            StrictMode.ViolationInfo info) {
13564        if (info == null) {
13565            return;
13566        }
13567        final boolean isSystemApp = process == null ||
13568                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13569                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13570        final String processName = process == null ? "unknown" : process.processName;
13571        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13572        final DropBoxManager dbox = (DropBoxManager)
13573                mContext.getSystemService(Context.DROPBOX_SERVICE);
13574
13575        // Exit early if the dropbox isn't configured to accept this report type.
13576        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13577
13578        boolean bufferWasEmpty;
13579        boolean needsFlush;
13580        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13581        synchronized (sb) {
13582            bufferWasEmpty = sb.length() == 0;
13583            appendDropBoxProcessHeaders(process, processName, sb);
13584            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13585            sb.append("System-App: ").append(isSystemApp).append("\n");
13586            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13587            if (info.violationNumThisLoop != 0) {
13588                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13589            }
13590            if (info.numAnimationsRunning != 0) {
13591                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13592            }
13593            if (info.broadcastIntentAction != null) {
13594                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13595            }
13596            if (info.durationMillis != -1) {
13597                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13598            }
13599            if (info.numInstances != -1) {
13600                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13601            }
13602            if (info.tags != null) {
13603                for (String tag : info.tags) {
13604                    sb.append("Span-Tag: ").append(tag).append("\n");
13605                }
13606            }
13607            sb.append("\n");
13608            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13609                sb.append(info.crashInfo.stackTrace);
13610                sb.append("\n");
13611            }
13612            if (info.message != null) {
13613                sb.append(info.message);
13614                sb.append("\n");
13615            }
13616
13617            // Only buffer up to ~64k.  Various logging bits truncate
13618            // things at 128k.
13619            needsFlush = (sb.length() > 64 * 1024);
13620        }
13621
13622        // Flush immediately if the buffer's grown too large, or this
13623        // is a non-system app.  Non-system apps are isolated with a
13624        // different tag & policy and not batched.
13625        //
13626        // Batching is useful during internal testing with
13627        // StrictMode settings turned up high.  Without batching,
13628        // thousands of separate files could be created on boot.
13629        if (!isSystemApp || needsFlush) {
13630            new Thread("Error dump: " + dropboxTag) {
13631                @Override
13632                public void run() {
13633                    String report;
13634                    synchronized (sb) {
13635                        report = sb.toString();
13636                        sb.delete(0, sb.length());
13637                        sb.trimToSize();
13638                    }
13639                    if (report.length() != 0) {
13640                        dbox.addText(dropboxTag, report);
13641                    }
13642                }
13643            }.start();
13644            return;
13645        }
13646
13647        // System app batching:
13648        if (!bufferWasEmpty) {
13649            // An existing dropbox-writing thread is outstanding, so
13650            // we don't need to start it up.  The existing thread will
13651            // catch the buffer appends we just did.
13652            return;
13653        }
13654
13655        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13656        // (After this point, we shouldn't access AMS internal data structures.)
13657        new Thread("Error dump: " + dropboxTag) {
13658            @Override
13659            public void run() {
13660                // 5 second sleep to let stacks arrive and be batched together
13661                try {
13662                    Thread.sleep(5000);  // 5 seconds
13663                } catch (InterruptedException e) {}
13664
13665                String errorReport;
13666                synchronized (mStrictModeBuffer) {
13667                    errorReport = mStrictModeBuffer.toString();
13668                    if (errorReport.length() == 0) {
13669                        return;
13670                    }
13671                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13672                    mStrictModeBuffer.trimToSize();
13673                }
13674                dbox.addText(dropboxTag, errorReport);
13675            }
13676        }.start();
13677    }
13678
13679    /**
13680     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13681     * @param app object of the crashing app, null for the system server
13682     * @param tag reported by the caller
13683     * @param system whether this wtf is coming from the system
13684     * @param crashInfo describing the context of the error
13685     * @return true if the process should exit immediately (WTF is fatal)
13686     */
13687    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13688            final ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
13689        final int callingUid = Binder.getCallingUid();
13690        final int callingPid = Binder.getCallingPid();
13691
13692        if (system) {
13693            // If this is coming from the system, we could very well have low-level
13694            // system locks held, so we want to do this all asynchronously.  And we
13695            // never want this to become fatal, so there is that too.
13696            mHandler.post(new Runnable() {
13697                @Override public void run() {
13698                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13699                }
13700            });
13701            return false;
13702        }
13703
13704        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13705                crashInfo);
13706
13707        final boolean isFatal = "eng".equals(Build.TYPE) || Settings.Global
13708                .getInt(mContext.getContentResolver(), Settings.Global.WTF_IS_FATAL, 0) != 0;
13709        final boolean isSystem = (r == null) || r.persistent;
13710
13711        if (isFatal && !isSystem) {
13712            mAppErrors.crashApplication(r, crashInfo);
13713            return true;
13714        } else {
13715            return false;
13716        }
13717    }
13718
13719    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13720            final ApplicationErrorReport.CrashInfo crashInfo) {
13721        final ProcessRecord r = findAppProcess(app, "WTF");
13722        final String processName = app == null ? "system_server"
13723                : (r == null ? "unknown" : r.processName);
13724
13725        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13726                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13727
13728        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13729
13730        return r;
13731    }
13732
13733    /**
13734     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13735     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13736     */
13737    private ProcessRecord findAppProcess(IBinder app, String reason) {
13738        if (app == null) {
13739            return null;
13740        }
13741
13742        synchronized (this) {
13743            final int NP = mProcessNames.getMap().size();
13744            for (int ip=0; ip<NP; ip++) {
13745                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13746                final int NA = apps.size();
13747                for (int ia=0; ia<NA; ia++) {
13748                    ProcessRecord p = apps.valueAt(ia);
13749                    if (p.thread != null && p.thread.asBinder() == app) {
13750                        return p;
13751                    }
13752                }
13753            }
13754
13755            Slog.w(TAG, "Can't find mystery application for " + reason
13756                    + " from pid=" + Binder.getCallingPid()
13757                    + " uid=" + Binder.getCallingUid() + ": " + app);
13758            return null;
13759        }
13760    }
13761
13762    /**
13763     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13764     * to append various headers to the dropbox log text.
13765     */
13766    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13767            StringBuilder sb) {
13768        // Watchdog thread ends up invoking this function (with
13769        // a null ProcessRecord) to add the stack file to dropbox.
13770        // Do not acquire a lock on this (am) in such cases, as it
13771        // could cause a potential deadlock, if and when watchdog
13772        // is invoked due to unavailability of lock on am and it
13773        // would prevent watchdog from killing system_server.
13774        if (process == null) {
13775            sb.append("Process: ").append(processName).append("\n");
13776            return;
13777        }
13778        // Note: ProcessRecord 'process' is guarded by the service
13779        // instance.  (notably process.pkgList, which could otherwise change
13780        // concurrently during execution of this method)
13781        synchronized (this) {
13782            sb.append("Process: ").append(processName).append("\n");
13783            int flags = process.info.flags;
13784            IPackageManager pm = AppGlobals.getPackageManager();
13785            sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
13786            for (int ip=0; ip<process.pkgList.size(); ip++) {
13787                String pkg = process.pkgList.keyAt(ip);
13788                sb.append("Package: ").append(pkg);
13789                try {
13790                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13791                    if (pi != null) {
13792                        sb.append(" v").append(pi.versionCode);
13793                        if (pi.versionName != null) {
13794                            sb.append(" (").append(pi.versionName).append(")");
13795                        }
13796                    }
13797                } catch (RemoteException e) {
13798                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13799                }
13800                sb.append("\n");
13801            }
13802        }
13803    }
13804
13805    private static String processClass(ProcessRecord process) {
13806        if (process == null || process.pid == MY_PID) {
13807            return "system_server";
13808        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13809            return "system_app";
13810        } else {
13811            return "data_app";
13812        }
13813    }
13814
13815    private volatile long mWtfClusterStart;
13816    private volatile int mWtfClusterCount;
13817
13818    /**
13819     * Write a description of an error (crash, WTF, ANR) to the drop box.
13820     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13821     * @param process which caused the error, null means the system server
13822     * @param activity which triggered the error, null if unknown
13823     * @param parent activity related to the error, null if unknown
13824     * @param subject line related to the error, null if absent
13825     * @param report in long form describing the error, null if absent
13826     * @param dataFile text file to include in the report, null if none
13827     * @param crashInfo giving an application stack trace, null if absent
13828     */
13829    public void addErrorToDropBox(String eventType,
13830            ProcessRecord process, String processName, ActivityRecord activity,
13831            ActivityRecord parent, String subject,
13832            final String report, final File dataFile,
13833            final ApplicationErrorReport.CrashInfo crashInfo) {
13834        // NOTE -- this must never acquire the ActivityManagerService lock,
13835        // otherwise the watchdog may be prevented from resetting the system.
13836
13837        // Bail early if not published yet
13838        if (ServiceManager.getService(Context.DROPBOX_SERVICE) == null) return;
13839        final DropBoxManager dbox = mContext.getSystemService(DropBoxManager.class);
13840
13841        // Exit early if the dropbox isn't configured to accept this report type.
13842        final String dropboxTag = processClass(process) + "_" + eventType;
13843        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13844
13845        // Rate-limit how often we're willing to do the heavy lifting below to
13846        // collect and record logs; currently 5 logs per 10 second period.
13847        final long now = SystemClock.elapsedRealtime();
13848        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13849            mWtfClusterStart = now;
13850            mWtfClusterCount = 1;
13851        } else {
13852            if (mWtfClusterCount++ >= 5) return;
13853        }
13854
13855        final StringBuilder sb = new StringBuilder(1024);
13856        appendDropBoxProcessHeaders(process, processName, sb);
13857        if (process != null) {
13858            sb.append("Foreground: ")
13859                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13860                    .append("\n");
13861        }
13862        if (activity != null) {
13863            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13864        }
13865        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13866            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13867        }
13868        if (parent != null && parent != activity) {
13869            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13870        }
13871        if (subject != null) {
13872            sb.append("Subject: ").append(subject).append("\n");
13873        }
13874        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13875        if (Debug.isDebuggerConnected()) {
13876            sb.append("Debugger: Connected\n");
13877        }
13878        sb.append("\n");
13879
13880        // Do the rest in a worker thread to avoid blocking the caller on I/O
13881        // (After this point, we shouldn't access AMS internal data structures.)
13882        Thread worker = new Thread("Error dump: " + dropboxTag) {
13883            @Override
13884            public void run() {
13885                if (report != null) {
13886                    sb.append(report);
13887                }
13888
13889                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13890                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13891                int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
13892                        - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
13893
13894                if (dataFile != null && maxDataFileSize > 0) {
13895                    try {
13896                        sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
13897                                    "\n\n[[TRUNCATED]]"));
13898                    } catch (IOException e) {
13899                        Slog.e(TAG, "Error reading " + dataFile, e);
13900                    }
13901                }
13902                if (crashInfo != null && crashInfo.stackTrace != null) {
13903                    sb.append(crashInfo.stackTrace);
13904                }
13905
13906                if (lines > 0) {
13907                    sb.append("\n");
13908
13909                    // Merge several logcat streams, and take the last N lines
13910                    InputStreamReader input = null;
13911                    try {
13912                        java.lang.Process logcat = new ProcessBuilder(
13913                                "/system/bin/timeout", "-k", "15s", "10s",
13914                                "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
13915                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13916                                        .redirectErrorStream(true).start();
13917
13918                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13919                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13920                        input = new InputStreamReader(logcat.getInputStream());
13921
13922                        int num;
13923                        char[] buf = new char[8192];
13924                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13925                    } catch (IOException e) {
13926                        Slog.e(TAG, "Error running logcat", e);
13927                    } finally {
13928                        if (input != null) try { input.close(); } catch (IOException e) {}
13929                    }
13930                }
13931
13932                dbox.addText(dropboxTag, sb.toString());
13933            }
13934        };
13935
13936        if (process == null) {
13937            // If process is null, we are being called from some internal code
13938            // and may be about to die -- run this synchronously.
13939            worker.run();
13940        } else {
13941            worker.start();
13942        }
13943    }
13944
13945    @Override
13946    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13947        enforceNotIsolatedCaller("getProcessesInErrorState");
13948        // assume our apps are happy - lazy create the list
13949        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13950
13951        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13952                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13953        int userId = UserHandle.getUserId(Binder.getCallingUid());
13954
13955        synchronized (this) {
13956
13957            // iterate across all processes
13958            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13959                ProcessRecord app = mLruProcesses.get(i);
13960                if (!allUsers && app.userId != userId) {
13961                    continue;
13962                }
13963                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13964                    // This one's in trouble, so we'll generate a report for it
13965                    // crashes are higher priority (in case there's a crash *and* an anr)
13966                    ActivityManager.ProcessErrorStateInfo report = null;
13967                    if (app.crashing) {
13968                        report = app.crashingReport;
13969                    } else if (app.notResponding) {
13970                        report = app.notRespondingReport;
13971                    }
13972
13973                    if (report != null) {
13974                        if (errList == null) {
13975                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13976                        }
13977                        errList.add(report);
13978                    } else {
13979                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13980                                " crashing = " + app.crashing +
13981                                " notResponding = " + app.notResponding);
13982                    }
13983                }
13984            }
13985        }
13986
13987        return errList;
13988    }
13989
13990    static int procStateToImportance(int procState, int memAdj,
13991            ActivityManager.RunningAppProcessInfo currApp) {
13992        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13993        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13994            currApp.lru = memAdj;
13995        } else {
13996            currApp.lru = 0;
13997        }
13998        return imp;
13999    }
14000
14001    private void fillInProcMemInfo(ProcessRecord app,
14002            ActivityManager.RunningAppProcessInfo outInfo) {
14003        outInfo.pid = app.pid;
14004        outInfo.uid = app.info.uid;
14005        if (mHeavyWeightProcess == app) {
14006            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
14007        }
14008        if (app.persistent) {
14009            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
14010        }
14011        if (app.activities.size() > 0) {
14012            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
14013        }
14014        outInfo.lastTrimLevel = app.trimMemoryLevel;
14015        int adj = app.curAdj;
14016        int procState = app.curProcState;
14017        outInfo.importance = procStateToImportance(procState, adj, outInfo);
14018        outInfo.importanceReasonCode = app.adjTypeCode;
14019        outInfo.processState = app.curProcState;
14020    }
14021
14022    @Override
14023    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
14024        enforceNotIsolatedCaller("getRunningAppProcesses");
14025
14026        final int callingUid = Binder.getCallingUid();
14027
14028        // Lazy instantiation of list
14029        List<ActivityManager.RunningAppProcessInfo> runList = null;
14030        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14031                callingUid) == PackageManager.PERMISSION_GRANTED;
14032        final int userId = UserHandle.getUserId(callingUid);
14033        final boolean allUids = isGetTasksAllowed(
14034                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
14035
14036        synchronized (this) {
14037            // Iterate across all processes
14038            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14039                ProcessRecord app = mLruProcesses.get(i);
14040                if ((!allUsers && app.userId != userId)
14041                        || (!allUids && app.uid != callingUid)) {
14042                    continue;
14043                }
14044                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
14045                    // Generate process state info for running application
14046                    ActivityManager.RunningAppProcessInfo currApp =
14047                        new ActivityManager.RunningAppProcessInfo(app.processName,
14048                                app.pid, app.getPackageList());
14049                    fillInProcMemInfo(app, currApp);
14050                    if (app.adjSource instanceof ProcessRecord) {
14051                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
14052                        currApp.importanceReasonImportance =
14053                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
14054                                        app.adjSourceProcState);
14055                    } else if (app.adjSource instanceof ActivityRecord) {
14056                        ActivityRecord r = (ActivityRecord)app.adjSource;
14057                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
14058                    }
14059                    if (app.adjTarget instanceof ComponentName) {
14060                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
14061                    }
14062                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
14063                    //        + " lru=" + currApp.lru);
14064                    if (runList == null) {
14065                        runList = new ArrayList<>();
14066                    }
14067                    runList.add(currApp);
14068                }
14069            }
14070        }
14071        return runList;
14072    }
14073
14074    @Override
14075    public List<ApplicationInfo> getRunningExternalApplications() {
14076        enforceNotIsolatedCaller("getRunningExternalApplications");
14077        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
14078        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
14079        if (runningApps != null && runningApps.size() > 0) {
14080            Set<String> extList = new HashSet<String>();
14081            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
14082                if (app.pkgList != null) {
14083                    for (String pkg : app.pkgList) {
14084                        extList.add(pkg);
14085                    }
14086                }
14087            }
14088            IPackageManager pm = AppGlobals.getPackageManager();
14089            for (String pkg : extList) {
14090                try {
14091                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
14092                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
14093                        retList.add(info);
14094                    }
14095                } catch (RemoteException e) {
14096                }
14097            }
14098        }
14099        return retList;
14100    }
14101
14102    @Override
14103    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
14104        enforceNotIsolatedCaller("getMyMemoryState");
14105        synchronized (this) {
14106            ProcessRecord proc;
14107            synchronized (mPidsSelfLocked) {
14108                proc = mPidsSelfLocked.get(Binder.getCallingPid());
14109            }
14110            fillInProcMemInfo(proc, outInfo);
14111        }
14112    }
14113
14114    @Override
14115    public int getMemoryTrimLevel() {
14116        enforceNotIsolatedCaller("getMyMemoryState");
14117        synchronized (this) {
14118            return mLastMemoryLevel;
14119        }
14120    }
14121
14122    @Override
14123    public void onShellCommand(FileDescriptor in, FileDescriptor out,
14124            FileDescriptor err, String[] args, ShellCallback callback,
14125            ResultReceiver resultReceiver) {
14126        (new ActivityManagerShellCommand(this, false)).exec(
14127                this, in, out, err, args, callback, resultReceiver);
14128    }
14129
14130    @Override
14131    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
14132        if (checkCallingPermission(android.Manifest.permission.DUMP)
14133                != PackageManager.PERMISSION_GRANTED) {
14134            pw.println("Permission Denial: can't dump ActivityManager from from pid="
14135                    + Binder.getCallingPid()
14136                    + ", uid=" + Binder.getCallingUid()
14137                    + " without permission "
14138                    + android.Manifest.permission.DUMP);
14139            return;
14140        }
14141
14142        boolean dumpAll = false;
14143        boolean dumpClient = false;
14144        boolean dumpCheckin = false;
14145        boolean dumpCheckinFormat = false;
14146        boolean dumpVisibleStacks = false;
14147        String dumpPackage = null;
14148
14149        int opti = 0;
14150        while (opti < args.length) {
14151            String opt = args[opti];
14152            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14153                break;
14154            }
14155            opti++;
14156            if ("-a".equals(opt)) {
14157                dumpAll = true;
14158            } else if ("-c".equals(opt)) {
14159                dumpClient = true;
14160            } else if ("-v".equals(opt)) {
14161                dumpVisibleStacks = true;
14162            } else if ("-p".equals(opt)) {
14163                if (opti < args.length) {
14164                    dumpPackage = args[opti];
14165                    opti++;
14166                } else {
14167                    pw.println("Error: -p option requires package argument");
14168                    return;
14169                }
14170                dumpClient = true;
14171            } else if ("--checkin".equals(opt)) {
14172                dumpCheckin = dumpCheckinFormat = true;
14173            } else if ("-C".equals(opt)) {
14174                dumpCheckinFormat = true;
14175            } else if ("-h".equals(opt)) {
14176                ActivityManagerShellCommand.dumpHelp(pw, true);
14177                return;
14178            } else {
14179                pw.println("Unknown argument: " + opt + "; use -h for help");
14180            }
14181        }
14182
14183        long origId = Binder.clearCallingIdentity();
14184        boolean more = false;
14185        // Is the caller requesting to dump a particular piece of data?
14186        if (opti < args.length) {
14187            String cmd = args[opti];
14188            opti++;
14189            if ("activities".equals(cmd) || "a".equals(cmd)) {
14190                synchronized (this) {
14191                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14192                }
14193            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
14194                synchronized (this) {
14195                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
14196                }
14197            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
14198                String[] newArgs;
14199                String name;
14200                if (opti >= args.length) {
14201                    name = null;
14202                    newArgs = EMPTY_STRING_ARRAY;
14203                } else {
14204                    dumpPackage = args[opti];
14205                    opti++;
14206                    newArgs = new String[args.length - opti];
14207                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14208                            args.length - opti);
14209                }
14210                synchronized (this) {
14211                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
14212                }
14213            } else if ("broadcast-stats".equals(cmd)) {
14214                String[] newArgs;
14215                String name;
14216                if (opti >= args.length) {
14217                    name = null;
14218                    newArgs = EMPTY_STRING_ARRAY;
14219                } else {
14220                    dumpPackage = args[opti];
14221                    opti++;
14222                    newArgs = new String[args.length - opti];
14223                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14224                            args.length - opti);
14225                }
14226                synchronized (this) {
14227                    if (dumpCheckinFormat) {
14228                        dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
14229                                dumpPackage);
14230                    } else {
14231                        dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
14232                    }
14233                }
14234            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
14235                String[] newArgs;
14236                String name;
14237                if (opti >= args.length) {
14238                    name = null;
14239                    newArgs = EMPTY_STRING_ARRAY;
14240                } else {
14241                    dumpPackage = args[opti];
14242                    opti++;
14243                    newArgs = new String[args.length - opti];
14244                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14245                            args.length - opti);
14246                }
14247                synchronized (this) {
14248                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
14249                }
14250            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
14251                String[] newArgs;
14252                String name;
14253                if (opti >= args.length) {
14254                    name = null;
14255                    newArgs = EMPTY_STRING_ARRAY;
14256                } else {
14257                    dumpPackage = args[opti];
14258                    opti++;
14259                    newArgs = new String[args.length - opti];
14260                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14261                            args.length - opti);
14262                }
14263                synchronized (this) {
14264                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
14265                }
14266            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
14267                synchronized (this) {
14268                    dumpOomLocked(fd, pw, args, opti, true);
14269                }
14270            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
14271                synchronized (this) {
14272                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
14273                }
14274            } else if ("provider".equals(cmd)) {
14275                String[] newArgs;
14276                String name;
14277                if (opti >= args.length) {
14278                    name = null;
14279                    newArgs = EMPTY_STRING_ARRAY;
14280                } else {
14281                    name = args[opti];
14282                    opti++;
14283                    newArgs = new String[args.length - opti];
14284                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14285                }
14286                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
14287                    pw.println("No providers match: " + name);
14288                    pw.println("Use -h for help.");
14289                }
14290            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
14291                synchronized (this) {
14292                    dumpProvidersLocked(fd, pw, args, opti, true, null);
14293                }
14294            } else if ("service".equals(cmd)) {
14295                String[] newArgs;
14296                String name;
14297                if (opti >= args.length) {
14298                    name = null;
14299                    newArgs = EMPTY_STRING_ARRAY;
14300                } else {
14301                    name = args[opti];
14302                    opti++;
14303                    newArgs = new String[args.length - opti];
14304                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14305                            args.length - opti);
14306                }
14307                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
14308                    pw.println("No services match: " + name);
14309                    pw.println("Use -h for help.");
14310                }
14311            } else if ("package".equals(cmd)) {
14312                String[] newArgs;
14313                if (opti >= args.length) {
14314                    pw.println("package: no package name specified");
14315                    pw.println("Use -h for help.");
14316                } else {
14317                    dumpPackage = args[opti];
14318                    opti++;
14319                    newArgs = new String[args.length - opti];
14320                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14321                            args.length - opti);
14322                    args = newArgs;
14323                    opti = 0;
14324                    more = true;
14325                }
14326            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
14327                synchronized (this) {
14328                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14329                }
14330            } else if ("services".equals(cmd) || "s".equals(cmd)) {
14331                if (dumpClient) {
14332                    ActiveServices.ServiceDumper dumper;
14333                    synchronized (this) {
14334                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14335                                dumpPackage);
14336                    }
14337                    dumper.dumpWithClient();
14338                } else {
14339                    synchronized (this) {
14340                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14341                                dumpPackage).dumpLocked();
14342                    }
14343                }
14344            } else if ("locks".equals(cmd)) {
14345                LockGuard.dump(fd, pw, args);
14346            } else {
14347                // Dumping a single activity?
14348                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll, dumpVisibleStacks)) {
14349                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
14350                    int res = shell.exec(this, null, fd, null, args, null,
14351                            new ResultReceiver(null));
14352                    if (res < 0) {
14353                        pw.println("Bad activity command, or no activities match: " + cmd);
14354                        pw.println("Use -h for help.");
14355                    }
14356                }
14357            }
14358            if (!more) {
14359                Binder.restoreCallingIdentity(origId);
14360                return;
14361            }
14362        }
14363
14364        // No piece of data specified, dump everything.
14365        if (dumpCheckinFormat) {
14366            dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
14367        } else if (dumpClient) {
14368            ActiveServices.ServiceDumper sdumper;
14369            synchronized (this) {
14370                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14371                pw.println();
14372                if (dumpAll) {
14373                    pw.println("-------------------------------------------------------------------------------");
14374                }
14375                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14376                pw.println();
14377                if (dumpAll) {
14378                    pw.println("-------------------------------------------------------------------------------");
14379                }
14380                if (dumpAll || dumpPackage != null) {
14381                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14382                    pw.println();
14383                    if (dumpAll) {
14384                        pw.println("-------------------------------------------------------------------------------");
14385                    }
14386                }
14387                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14388                pw.println();
14389                if (dumpAll) {
14390                    pw.println("-------------------------------------------------------------------------------");
14391                }
14392                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14393                pw.println();
14394                if (dumpAll) {
14395                    pw.println("-------------------------------------------------------------------------------");
14396                }
14397                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
14398                        dumpPackage);
14399            }
14400            sdumper.dumpWithClient();
14401            pw.println();
14402            synchronized (this) {
14403                if (dumpAll) {
14404                    pw.println("-------------------------------------------------------------------------------");
14405                }
14406                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14407                pw.println();
14408                if (dumpAll) {
14409                    pw.println("-------------------------------------------------------------------------------");
14410                }
14411                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14412                if (mAssociations.size() > 0) {
14413                    pw.println();
14414                    if (dumpAll) {
14415                        pw.println("-------------------------------------------------------------------------------");
14416                    }
14417                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14418                }
14419                pw.println();
14420                if (dumpAll) {
14421                    pw.println("-------------------------------------------------------------------------------");
14422                }
14423                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14424            }
14425
14426        } else {
14427            synchronized (this) {
14428                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14429                pw.println();
14430                if (dumpAll) {
14431                    pw.println("-------------------------------------------------------------------------------");
14432                }
14433                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14434                pw.println();
14435                if (dumpAll) {
14436                    pw.println("-------------------------------------------------------------------------------");
14437                }
14438                if (dumpAll || dumpPackage != null) {
14439                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14440                    pw.println();
14441                    if (dumpAll) {
14442                        pw.println("-------------------------------------------------------------------------------");
14443                    }
14444                }
14445                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14446                pw.println();
14447                if (dumpAll) {
14448                    pw.println("-------------------------------------------------------------------------------");
14449                }
14450                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14451                pw.println();
14452                if (dumpAll) {
14453                    pw.println("-------------------------------------------------------------------------------");
14454                }
14455                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
14456                        .dumpLocked();
14457                pw.println();
14458                if (dumpAll) {
14459                    pw.println("-------------------------------------------------------------------------------");
14460                }
14461                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14462                pw.println();
14463                if (dumpAll) {
14464                    pw.println("-------------------------------------------------------------------------------");
14465                }
14466                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14467                if (mAssociations.size() > 0) {
14468                    pw.println();
14469                    if (dumpAll) {
14470                        pw.println("-------------------------------------------------------------------------------");
14471                    }
14472                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14473                }
14474                pw.println();
14475                if (dumpAll) {
14476                    pw.println("-------------------------------------------------------------------------------");
14477                }
14478                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14479            }
14480        }
14481        Binder.restoreCallingIdentity(origId);
14482    }
14483
14484    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14485            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14486        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
14487
14488        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
14489                dumpPackage);
14490        boolean needSep = printedAnything;
14491
14492        boolean printed = ActivityStackSupervisor.printThisActivity(pw,
14493                mStackSupervisor.getResumedActivityLocked(),
14494                dumpPackage, needSep, "  ResumedActivity: ");
14495        if (printed) {
14496            printedAnything = true;
14497            needSep = false;
14498        }
14499
14500        if (dumpPackage == null) {
14501            if (needSep) {
14502                pw.println();
14503            }
14504            needSep = true;
14505            printedAnything = true;
14506            mStackSupervisor.dump(pw, "  ");
14507        }
14508
14509        if (!printedAnything) {
14510            pw.println("  (nothing)");
14511        }
14512    }
14513
14514    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14515            int opti, boolean dumpAll, String dumpPackage) {
14516        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14517
14518        boolean printedAnything = false;
14519
14520        if (mRecentTasks != null && mRecentTasks.size() > 0) {
14521            boolean printedHeader = false;
14522
14523            final int N = mRecentTasks.size();
14524            for (int i=0; i<N; i++) {
14525                TaskRecord tr = mRecentTasks.get(i);
14526                if (dumpPackage != null) {
14527                    if (tr.realActivity == null ||
14528                            !dumpPackage.equals(tr.realActivity.getPackageName())) {
14529                        continue;
14530                    }
14531                }
14532                if (!printedHeader) {
14533                    pw.println("  Recent tasks:");
14534                    printedHeader = true;
14535                    printedAnything = true;
14536                }
14537                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
14538                        pw.println(tr);
14539                if (dumpAll) {
14540                    mRecentTasks.get(i).dump(pw, "    ");
14541                }
14542            }
14543        }
14544
14545        if (!printedAnything) {
14546            pw.println("  (nothing)");
14547        }
14548    }
14549
14550    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14551            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14552        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14553
14554        int dumpUid = 0;
14555        if (dumpPackage != null) {
14556            IPackageManager pm = AppGlobals.getPackageManager();
14557            try {
14558                dumpUid = pm.getPackageUid(dumpPackage, MATCH_ANY_USER, 0);
14559            } catch (RemoteException e) {
14560            }
14561        }
14562
14563        boolean printedAnything = false;
14564
14565        final long now = SystemClock.uptimeMillis();
14566
14567        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14568            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14569                    = mAssociations.valueAt(i1);
14570            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14571                SparseArray<ArrayMap<String, Association>> sourceUids
14572                        = targetComponents.valueAt(i2);
14573                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14574                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14575                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14576                        Association ass = sourceProcesses.valueAt(i4);
14577                        if (dumpPackage != null) {
14578                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14579                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14580                                continue;
14581                            }
14582                        }
14583                        printedAnything = true;
14584                        pw.print("  ");
14585                        pw.print(ass.mTargetProcess);
14586                        pw.print("/");
14587                        UserHandle.formatUid(pw, ass.mTargetUid);
14588                        pw.print(" <- ");
14589                        pw.print(ass.mSourceProcess);
14590                        pw.print("/");
14591                        UserHandle.formatUid(pw, ass.mSourceUid);
14592                        pw.println();
14593                        pw.print("    via ");
14594                        pw.print(ass.mTargetComponent.flattenToShortString());
14595                        pw.println();
14596                        pw.print("    ");
14597                        long dur = ass.mTime;
14598                        if (ass.mNesting > 0) {
14599                            dur += now - ass.mStartTime;
14600                        }
14601                        TimeUtils.formatDuration(dur, pw);
14602                        pw.print(" (");
14603                        pw.print(ass.mCount);
14604                        pw.print(" times)");
14605                        pw.print("  ");
14606                        for (int i=0; i<ass.mStateTimes.length; i++) {
14607                            long amt = ass.mStateTimes[i];
14608                            if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
14609                                amt += now - ass.mLastStateUptime;
14610                            }
14611                            if (amt != 0) {
14612                                pw.print(" ");
14613                                pw.print(ProcessList.makeProcStateString(
14614                                            i + ActivityManager.MIN_PROCESS_STATE));
14615                                pw.print("=");
14616                                TimeUtils.formatDuration(amt, pw);
14617                                if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
14618                                    pw.print("*");
14619                                }
14620                            }
14621                        }
14622                        pw.println();
14623                        if (ass.mNesting > 0) {
14624                            pw.print("    Currently active: ");
14625                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
14626                            pw.println();
14627                        }
14628                    }
14629                }
14630            }
14631
14632        }
14633
14634        if (!printedAnything) {
14635            pw.println("  (nothing)");
14636        }
14637    }
14638
14639    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14640            String header, boolean needSep) {
14641        boolean printed = false;
14642        int whichAppId = -1;
14643        if (dumpPackage != null) {
14644            try {
14645                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14646                        dumpPackage, 0);
14647                whichAppId = UserHandle.getAppId(info.uid);
14648            } catch (NameNotFoundException e) {
14649                e.printStackTrace();
14650            }
14651        }
14652        for (int i=0; i<uids.size(); i++) {
14653            UidRecord uidRec = uids.valueAt(i);
14654            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14655                continue;
14656            }
14657            if (!printed) {
14658                printed = true;
14659                if (needSep) {
14660                    pw.println();
14661                }
14662                pw.print("  ");
14663                pw.println(header);
14664                needSep = true;
14665            }
14666            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14667            pw.print(": "); pw.println(uidRec);
14668        }
14669        return printed;
14670    }
14671
14672    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14673            int opti, boolean dumpAll, String dumpPackage) {
14674        boolean needSep = false;
14675        boolean printedAnything = false;
14676        int numPers = 0;
14677
14678        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14679
14680        if (dumpAll) {
14681            final int NP = mProcessNames.getMap().size();
14682            for (int ip=0; ip<NP; ip++) {
14683                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14684                final int NA = procs.size();
14685                for (int ia=0; ia<NA; ia++) {
14686                    ProcessRecord r = procs.valueAt(ia);
14687                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14688                        continue;
14689                    }
14690                    if (!needSep) {
14691                        pw.println("  All known processes:");
14692                        needSep = true;
14693                        printedAnything = true;
14694                    }
14695                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14696                        pw.print(" UID "); pw.print(procs.keyAt(ia));
14697                        pw.print(" "); pw.println(r);
14698                    r.dump(pw, "    ");
14699                    if (r.persistent) {
14700                        numPers++;
14701                    }
14702                }
14703            }
14704        }
14705
14706        if (mIsolatedProcesses.size() > 0) {
14707            boolean printed = false;
14708            for (int i=0; i<mIsolatedProcesses.size(); i++) {
14709                ProcessRecord r = mIsolatedProcesses.valueAt(i);
14710                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14711                    continue;
14712                }
14713                if (!printed) {
14714                    if (needSep) {
14715                        pw.println();
14716                    }
14717                    pw.println("  Isolated process list (sorted by uid):");
14718                    printedAnything = true;
14719                    printed = true;
14720                    needSep = true;
14721                }
14722                pw.println(String.format("%sIsolated #%2d: %s",
14723                        "    ", i, r.toString()));
14724            }
14725        }
14726
14727        if (mActiveUids.size() > 0) {
14728            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14729                printedAnything = needSep = true;
14730            }
14731        }
14732        if (mValidateUids.size() > 0) {
14733            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14734                printedAnything = needSep = true;
14735            }
14736        }
14737
14738        if (mLruProcesses.size() > 0) {
14739            if (needSep) {
14740                pw.println();
14741            }
14742            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14743                    pw.print(" total, non-act at ");
14744                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14745                    pw.print(", non-svc at ");
14746                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14747                    pw.println("):");
14748            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14749            needSep = true;
14750            printedAnything = true;
14751        }
14752
14753        if (dumpAll || dumpPackage != null) {
14754            synchronized (mPidsSelfLocked) {
14755                boolean printed = false;
14756                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14757                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14758                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14759                        continue;
14760                    }
14761                    if (!printed) {
14762                        if (needSep) pw.println();
14763                        needSep = true;
14764                        pw.println("  PID mappings:");
14765                        printed = true;
14766                        printedAnything = true;
14767                    }
14768                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14769                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14770                }
14771            }
14772        }
14773
14774        if (mForegroundProcesses.size() > 0) {
14775            synchronized (mPidsSelfLocked) {
14776                boolean printed = false;
14777                for (int i=0; i<mForegroundProcesses.size(); i++) {
14778                    ProcessRecord r = mPidsSelfLocked.get(
14779                            mForegroundProcesses.valueAt(i).pid);
14780                    if (dumpPackage != null && (r == null
14781                            || !r.pkgList.containsKey(dumpPackage))) {
14782                        continue;
14783                    }
14784                    if (!printed) {
14785                        if (needSep) pw.println();
14786                        needSep = true;
14787                        pw.println("  Foreground Processes:");
14788                        printed = true;
14789                        printedAnything = true;
14790                    }
14791                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14792                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14793                }
14794            }
14795        }
14796
14797        if (mPersistentStartingProcesses.size() > 0) {
14798            if (needSep) pw.println();
14799            needSep = true;
14800            printedAnything = true;
14801            pw.println("  Persisent processes that are starting:");
14802            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14803                    "Starting Norm", "Restarting PERS", dumpPackage);
14804        }
14805
14806        if (mRemovedProcesses.size() > 0) {
14807            if (needSep) pw.println();
14808            needSep = true;
14809            printedAnything = true;
14810            pw.println("  Processes that are being removed:");
14811            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14812                    "Removed Norm", "Removed PERS", dumpPackage);
14813        }
14814
14815        if (mProcessesOnHold.size() > 0) {
14816            if (needSep) pw.println();
14817            needSep = true;
14818            printedAnything = true;
14819            pw.println("  Processes that are on old until the system is ready:");
14820            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14821                    "OnHold Norm", "OnHold PERS", dumpPackage);
14822        }
14823
14824        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14825
14826        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14827        if (needSep) {
14828            printedAnything = true;
14829        }
14830
14831        if (dumpPackage == null) {
14832            pw.println();
14833            needSep = false;
14834            mUserController.dump(pw, dumpAll);
14835        }
14836        if (mHomeProcess != null && (dumpPackage == null
14837                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14838            if (needSep) {
14839                pw.println();
14840                needSep = false;
14841            }
14842            pw.println("  mHomeProcess: " + mHomeProcess);
14843        }
14844        if (mPreviousProcess != null && (dumpPackage == null
14845                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14846            if (needSep) {
14847                pw.println();
14848                needSep = false;
14849            }
14850            pw.println("  mPreviousProcess: " + mPreviousProcess);
14851        }
14852        if (dumpAll) {
14853            StringBuilder sb = new StringBuilder(128);
14854            sb.append("  mPreviousProcessVisibleTime: ");
14855            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14856            pw.println(sb);
14857        }
14858        if (mHeavyWeightProcess != null && (dumpPackage == null
14859                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14860            if (needSep) {
14861                pw.println();
14862                needSep = false;
14863            }
14864            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14865        }
14866        if (dumpPackage == null) {
14867            pw.println("  mGlobalConfiguration: " + getGlobalConfiguration());
14868            mStackSupervisor.dumpDisplayConfigs(pw, "  ");
14869        }
14870        if (dumpAll) {
14871            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14872            if (mCompatModePackages.getPackages().size() > 0) {
14873                boolean printed = false;
14874                for (Map.Entry<String, Integer> entry
14875                        : mCompatModePackages.getPackages().entrySet()) {
14876                    String pkg = entry.getKey();
14877                    int mode = entry.getValue();
14878                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14879                        continue;
14880                    }
14881                    if (!printed) {
14882                        pw.println("  mScreenCompatPackages:");
14883                        printed = true;
14884                    }
14885                    pw.print("    "); pw.print(pkg); pw.print(": ");
14886                            pw.print(mode); pw.println();
14887                }
14888            }
14889            final int NI = mUidObservers.getRegisteredCallbackCount();
14890            boolean printed = false;
14891            for (int i=0; i<NI; i++) {
14892                final UidObserverRegistration reg = (UidObserverRegistration)
14893                        mUidObservers.getRegisteredCallbackCookie(i);
14894                if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
14895                    if (!printed) {
14896                        pw.println("  mUidObservers:");
14897                        printed = true;
14898                    }
14899                    pw.print("    "); UserHandle.formatUid(pw, reg.uid);
14900                    pw.print(" "); pw.print(reg.pkg); pw.print(":");
14901                    if ((reg.which&ActivityManager.UID_OBSERVER_IDLE) != 0) {
14902                        pw.print(" IDLE");
14903                    }
14904                    if ((reg.which&ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
14905                        pw.print(" ACT" );
14906                    }
14907                    if ((reg.which&ActivityManager.UID_OBSERVER_GONE) != 0) {
14908                        pw.print(" GONE");
14909                    }
14910                    if ((reg.which&ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
14911                        pw.print(" STATE");
14912                        pw.print(" (cut="); pw.print(reg.cutpoint);
14913                        pw.print(")");
14914                    }
14915                    pw.println();
14916                    if (reg.lastProcStates != null) {
14917                        final int NJ = reg.lastProcStates.size();
14918                        for (int j=0; j<NJ; j++) {
14919                            pw.print("      Last ");
14920                            UserHandle.formatUid(pw, reg.lastProcStates.keyAt(j));
14921                            pw.print(": "); pw.println(reg.lastProcStates.valueAt(j));
14922                        }
14923                    }
14924                }
14925            }
14926        }
14927        if (dumpPackage == null) {
14928            pw.println("  mWakefulness="
14929                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14930            pw.println("  mSleepTokens=" + mSleepTokens);
14931            pw.println("  mSleeping=" + mSleeping);
14932            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14933            if (mRunningVoice != null) {
14934                pw.println("  mRunningVoice=" + mRunningVoice);
14935                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14936            }
14937        }
14938        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14939                || mOrigWaitForDebugger) {
14940            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14941                    || dumpPackage.equals(mOrigDebugApp)) {
14942                if (needSep) {
14943                    pw.println();
14944                    needSep = false;
14945                }
14946                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14947                        + " mDebugTransient=" + mDebugTransient
14948                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14949            }
14950        }
14951        if (mCurAppTimeTracker != null) {
14952            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14953        }
14954        if (mMemWatchProcesses.getMap().size() > 0) {
14955            pw.println("  Mem watch processes:");
14956            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14957                    = mMemWatchProcesses.getMap();
14958            for (int i=0; i<procs.size(); i++) {
14959                final String proc = procs.keyAt(i);
14960                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14961                for (int j=0; j<uids.size(); j++) {
14962                    if (needSep) {
14963                        pw.println();
14964                        needSep = false;
14965                    }
14966                    StringBuilder sb = new StringBuilder();
14967                    sb.append("    ").append(proc).append('/');
14968                    UserHandle.formatUid(sb, uids.keyAt(j));
14969                    Pair<Long, String> val = uids.valueAt(j);
14970                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14971                    if (val.second != null) {
14972                        sb.append(", report to ").append(val.second);
14973                    }
14974                    pw.println(sb.toString());
14975                }
14976            }
14977            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14978            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14979            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14980                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14981        }
14982        if (mTrackAllocationApp != null) {
14983            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14984                if (needSep) {
14985                    pw.println();
14986                    needSep = false;
14987                }
14988                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14989            }
14990        }
14991        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14992                || mProfileFd != null) {
14993            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14994                if (needSep) {
14995                    pw.println();
14996                    needSep = false;
14997                }
14998                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14999                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
15000                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
15001                        + mAutoStopProfiler);
15002                pw.println("  mProfileType=" + mProfileType);
15003            }
15004        }
15005        if (mNativeDebuggingApp != null) {
15006            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
15007                if (needSep) {
15008                    pw.println();
15009                    needSep = false;
15010                }
15011                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
15012            }
15013        }
15014        if (dumpPackage == null) {
15015            if (mAlwaysFinishActivities) {
15016                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities);
15017            }
15018            if (mController != null) {
15019                pw.println("  mController=" + mController
15020                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
15021            }
15022            if (dumpAll) {
15023                pw.println("  Total persistent processes: " + numPers);
15024                pw.println("  mProcessesReady=" + mProcessesReady
15025                        + " mSystemReady=" + mSystemReady
15026                        + " mBooted=" + mBooted
15027                        + " mFactoryTest=" + mFactoryTest);
15028                pw.println("  mBooting=" + mBooting
15029                        + " mCallFinishBooting=" + mCallFinishBooting
15030                        + " mBootAnimationComplete=" + mBootAnimationComplete);
15031                pw.print("  mLastPowerCheckRealtime=");
15032                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
15033                        pw.println("");
15034                pw.print("  mLastPowerCheckUptime=");
15035                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
15036                        pw.println("");
15037                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
15038                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
15039                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
15040                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
15041                        + " (" + mLruProcesses.size() + " total)"
15042                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
15043                        + " mNumServiceProcs=" + mNumServiceProcs
15044                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
15045                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
15046                        + " mLastMemoryLevel=" + mLastMemoryLevel
15047                        + " mLastNumProcesses=" + mLastNumProcesses);
15048                long now = SystemClock.uptimeMillis();
15049                pw.print("  mLastIdleTime=");
15050                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
15051                        pw.print(" mLowRamSinceLastIdle=");
15052                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
15053                        pw.println();
15054            }
15055        }
15056
15057        if (!printedAnything) {
15058            pw.println("  (nothing)");
15059        }
15060    }
15061
15062    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
15063            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
15064        if (mProcessesToGc.size() > 0) {
15065            boolean printed = false;
15066            long now = SystemClock.uptimeMillis();
15067            for (int i=0; i<mProcessesToGc.size(); i++) {
15068                ProcessRecord proc = mProcessesToGc.get(i);
15069                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
15070                    continue;
15071                }
15072                if (!printed) {
15073                    if (needSep) pw.println();
15074                    needSep = true;
15075                    pw.println("  Processes that are waiting to GC:");
15076                    printed = true;
15077                }
15078                pw.print("    Process "); pw.println(proc);
15079                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
15080                        pw.print(", last gced=");
15081                        pw.print(now-proc.lastRequestedGc);
15082                        pw.print(" ms ago, last lowMem=");
15083                        pw.print(now-proc.lastLowMemory);
15084                        pw.println(" ms ago");
15085
15086            }
15087        }
15088        return needSep;
15089    }
15090
15091    void printOomLevel(PrintWriter pw, String name, int adj) {
15092        pw.print("    ");
15093        if (adj >= 0) {
15094            pw.print(' ');
15095            if (adj < 10) pw.print(' ');
15096        } else {
15097            if (adj > -10) pw.print(' ');
15098        }
15099        pw.print(adj);
15100        pw.print(": ");
15101        pw.print(name);
15102        pw.print(" (");
15103        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
15104        pw.println(")");
15105    }
15106
15107    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15108            int opti, boolean dumpAll) {
15109        boolean needSep = false;
15110
15111        if (mLruProcesses.size() > 0) {
15112            if (needSep) pw.println();
15113            needSep = true;
15114            pw.println("  OOM levels:");
15115            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
15116            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
15117            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
15118            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
15119            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
15120            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
15121            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
15122            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
15123            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
15124            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
15125            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
15126            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
15127            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
15128            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
15129
15130            if (needSep) pw.println();
15131            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
15132                    pw.print(" total, non-act at ");
15133                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15134                    pw.print(", non-svc at ");
15135                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15136                    pw.println("):");
15137            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
15138            needSep = true;
15139        }
15140
15141        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
15142
15143        pw.println();
15144        pw.println("  mHomeProcess: " + mHomeProcess);
15145        pw.println("  mPreviousProcess: " + mPreviousProcess);
15146        if (mHeavyWeightProcess != null) {
15147            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
15148        }
15149
15150        return true;
15151    }
15152
15153    /**
15154     * There are three ways to call this:
15155     *  - no provider specified: dump all the providers
15156     *  - a flattened component name that matched an existing provider was specified as the
15157     *    first arg: dump that one provider
15158     *  - the first arg isn't the flattened component name of an existing provider:
15159     *    dump all providers whose component contains the first arg as a substring
15160     */
15161    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15162            int opti, boolean dumpAll) {
15163        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
15164    }
15165
15166    static class ItemMatcher {
15167        ArrayList<ComponentName> components;
15168        ArrayList<String> strings;
15169        ArrayList<Integer> objects;
15170        boolean all;
15171
15172        ItemMatcher() {
15173            all = true;
15174        }
15175
15176        void build(String name) {
15177            ComponentName componentName = ComponentName.unflattenFromString(name);
15178            if (componentName != null) {
15179                if (components == null) {
15180                    components = new ArrayList<ComponentName>();
15181                }
15182                components.add(componentName);
15183                all = false;
15184            } else {
15185                int objectId = 0;
15186                // Not a '/' separated full component name; maybe an object ID?
15187                try {
15188                    objectId = Integer.parseInt(name, 16);
15189                    if (objects == null) {
15190                        objects = new ArrayList<Integer>();
15191                    }
15192                    objects.add(objectId);
15193                    all = false;
15194                } catch (RuntimeException e) {
15195                    // Not an integer; just do string match.
15196                    if (strings == null) {
15197                        strings = new ArrayList<String>();
15198                    }
15199                    strings.add(name);
15200                    all = false;
15201                }
15202            }
15203        }
15204
15205        int build(String[] args, int opti) {
15206            for (; opti<args.length; opti++) {
15207                String name = args[opti];
15208                if ("--".equals(name)) {
15209                    return opti+1;
15210                }
15211                build(name);
15212            }
15213            return opti;
15214        }
15215
15216        boolean match(Object object, ComponentName comp) {
15217            if (all) {
15218                return true;
15219            }
15220            if (components != null) {
15221                for (int i=0; i<components.size(); i++) {
15222                    if (components.get(i).equals(comp)) {
15223                        return true;
15224                    }
15225                }
15226            }
15227            if (objects != null) {
15228                for (int i=0; i<objects.size(); i++) {
15229                    if (System.identityHashCode(object) == objects.get(i)) {
15230                        return true;
15231                    }
15232                }
15233            }
15234            if (strings != null) {
15235                String flat = comp.flattenToString();
15236                for (int i=0; i<strings.size(); i++) {
15237                    if (flat.contains(strings.get(i))) {
15238                        return true;
15239                    }
15240                }
15241            }
15242            return false;
15243        }
15244    }
15245
15246    /**
15247     * There are three things that cmd can be:
15248     *  - a flattened component name that matches an existing activity
15249     *  - the cmd arg isn't the flattened component name of an existing activity:
15250     *    dump all activity whose component contains the cmd as a substring
15251     *  - A hex number of the ActivityRecord object instance.
15252     */
15253    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15254            int opti, boolean dumpAll, boolean dumpVisibleStacks) {
15255        ArrayList<ActivityRecord> activities;
15256
15257        synchronized (this) {
15258            activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacks);
15259        }
15260
15261        if (activities.size() <= 0) {
15262            return false;
15263        }
15264
15265        String[] newArgs = new String[args.length - opti];
15266        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15267
15268        TaskRecord lastTask = null;
15269        boolean needSep = false;
15270        for (int i=activities.size()-1; i>=0; i--) {
15271            ActivityRecord r = activities.get(i);
15272            if (needSep) {
15273                pw.println();
15274            }
15275            needSep = true;
15276            synchronized (this) {
15277                if (lastTask != r.task) {
15278                    lastTask = r.task;
15279                    pw.print("TASK "); pw.print(lastTask.affinity);
15280                            pw.print(" id="); pw.print(lastTask.taskId);
15281                            pw.print(" userId="); pw.println(lastTask.userId);
15282                    if (dumpAll) {
15283                        lastTask.dump(pw, "  ");
15284                    }
15285                }
15286            }
15287            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
15288        }
15289        return true;
15290    }
15291
15292    /**
15293     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
15294     * there is a thread associated with the activity.
15295     */
15296    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
15297            final ActivityRecord r, String[] args, boolean dumpAll) {
15298        String innerPrefix = prefix + "  ";
15299        synchronized (this) {
15300            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
15301                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
15302                    pw.print(" pid=");
15303                    if (r.app != null) pw.println(r.app.pid);
15304                    else pw.println("(not running)");
15305            if (dumpAll) {
15306                r.dump(pw, innerPrefix);
15307            }
15308        }
15309        if (r.app != null && r.app.thread != null) {
15310            // flush anything that is already in the PrintWriter since the thread is going
15311            // to write to the file descriptor directly
15312            pw.flush();
15313            try {
15314                TransferPipe tp = new TransferPipe();
15315                try {
15316                    r.app.thread.dumpActivity(tp.getWriteFd(),
15317                            r.appToken, innerPrefix, args);
15318                    tp.go(fd);
15319                } finally {
15320                    tp.kill();
15321                }
15322            } catch (IOException e) {
15323                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
15324            } catch (RemoteException e) {
15325                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
15326            }
15327        }
15328    }
15329
15330    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15331            int opti, boolean dumpAll, String dumpPackage) {
15332        boolean needSep = false;
15333        boolean onlyHistory = false;
15334        boolean printedAnything = false;
15335
15336        if ("history".equals(dumpPackage)) {
15337            if (opti < args.length && "-s".equals(args[opti])) {
15338                dumpAll = false;
15339            }
15340            onlyHistory = true;
15341            dumpPackage = null;
15342        }
15343
15344        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
15345        if (!onlyHistory && dumpAll) {
15346            if (mRegisteredReceivers.size() > 0) {
15347                boolean printed = false;
15348                Iterator it = mRegisteredReceivers.values().iterator();
15349                while (it.hasNext()) {
15350                    ReceiverList r = (ReceiverList)it.next();
15351                    if (dumpPackage != null && (r.app == null ||
15352                            !dumpPackage.equals(r.app.info.packageName))) {
15353                        continue;
15354                    }
15355                    if (!printed) {
15356                        pw.println("  Registered Receivers:");
15357                        needSep = true;
15358                        printed = true;
15359                        printedAnything = true;
15360                    }
15361                    pw.print("  * "); pw.println(r);
15362                    r.dump(pw, "    ");
15363                }
15364            }
15365
15366            if (mReceiverResolver.dump(pw, needSep ?
15367                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
15368                    "    ", dumpPackage, false, false)) {
15369                needSep = true;
15370                printedAnything = true;
15371            }
15372        }
15373
15374        for (BroadcastQueue q : mBroadcastQueues) {
15375            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
15376            printedAnything |= needSep;
15377        }
15378
15379        needSep = true;
15380
15381        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
15382            for (int user=0; user<mStickyBroadcasts.size(); user++) {
15383                if (needSep) {
15384                    pw.println();
15385                }
15386                needSep = true;
15387                printedAnything = true;
15388                pw.print("  Sticky broadcasts for user ");
15389                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
15390                StringBuilder sb = new StringBuilder(128);
15391                for (Map.Entry<String, ArrayList<Intent>> ent
15392                        : mStickyBroadcasts.valueAt(user).entrySet()) {
15393                    pw.print("  * Sticky action "); pw.print(ent.getKey());
15394                    if (dumpAll) {
15395                        pw.println(":");
15396                        ArrayList<Intent> intents = ent.getValue();
15397                        final int N = intents.size();
15398                        for (int i=0; i<N; i++) {
15399                            sb.setLength(0);
15400                            sb.append("    Intent: ");
15401                            intents.get(i).toShortString(sb, false, true, false, false);
15402                            pw.println(sb.toString());
15403                            Bundle bundle = intents.get(i).getExtras();
15404                            if (bundle != null) {
15405                                pw.print("      ");
15406                                pw.println(bundle.toString());
15407                            }
15408                        }
15409                    } else {
15410                        pw.println("");
15411                    }
15412                }
15413            }
15414        }
15415
15416        if (!onlyHistory && dumpAll) {
15417            pw.println();
15418            for (BroadcastQueue queue : mBroadcastQueues) {
15419                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
15420                        + queue.mBroadcastsScheduled);
15421            }
15422            pw.println("  mHandler:");
15423            mHandler.dump(new PrintWriterPrinter(pw), "    ");
15424            needSep = true;
15425            printedAnything = true;
15426        }
15427
15428        if (!printedAnything) {
15429            pw.println("  (nothing)");
15430        }
15431    }
15432
15433    void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15434            int opti, boolean dumpAll, String dumpPackage) {
15435        if (mCurBroadcastStats == null) {
15436            return;
15437        }
15438
15439        pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
15440        final long now = SystemClock.elapsedRealtime();
15441        if (mLastBroadcastStats != null) {
15442            pw.print("  Last stats (from ");
15443            TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
15444            pw.print(" to ");
15445            TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
15446            pw.print(", ");
15447            TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
15448                    - mLastBroadcastStats.mStartUptime, pw);
15449            pw.println(" uptime):");
15450            if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15451                pw.println("    (nothing)");
15452            }
15453            pw.println();
15454        }
15455        pw.print("  Current stats (from ");
15456        TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
15457        pw.print(" to now, ");
15458        TimeUtils.formatDuration(SystemClock.uptimeMillis()
15459                - mCurBroadcastStats.mStartUptime, pw);
15460        pw.println(" uptime):");
15461        if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15462            pw.println("    (nothing)");
15463        }
15464    }
15465
15466    void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15467            int opti, boolean fullCheckin, String dumpPackage) {
15468        if (mCurBroadcastStats == null) {
15469            return;
15470        }
15471
15472        if (mLastBroadcastStats != null) {
15473            mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15474            if (fullCheckin) {
15475                mLastBroadcastStats = null;
15476                return;
15477            }
15478        }
15479        mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15480        if (fullCheckin) {
15481            mCurBroadcastStats = null;
15482        }
15483    }
15484
15485    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15486            int opti, boolean dumpAll, String dumpPackage) {
15487        boolean needSep;
15488        boolean printedAnything = false;
15489
15490        ItemMatcher matcher = new ItemMatcher();
15491        matcher.build(args, opti);
15492
15493        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
15494
15495        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
15496        printedAnything |= needSep;
15497
15498        if (mLaunchingProviders.size() > 0) {
15499            boolean printed = false;
15500            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
15501                ContentProviderRecord r = mLaunchingProviders.get(i);
15502                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
15503                    continue;
15504                }
15505                if (!printed) {
15506                    if (needSep) pw.println();
15507                    needSep = true;
15508                    pw.println("  Launching content providers:");
15509                    printed = true;
15510                    printedAnything = true;
15511                }
15512                pw.print("  Launching #"); pw.print(i); pw.print(": ");
15513                        pw.println(r);
15514            }
15515        }
15516
15517        if (!printedAnything) {
15518            pw.println("  (nothing)");
15519        }
15520    }
15521
15522    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15523            int opti, boolean dumpAll, String dumpPackage) {
15524        boolean needSep = false;
15525        boolean printedAnything = false;
15526
15527        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
15528
15529        if (mGrantedUriPermissions.size() > 0) {
15530            boolean printed = false;
15531            int dumpUid = -2;
15532            if (dumpPackage != null) {
15533                try {
15534                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
15535                            MATCH_ANY_USER, 0);
15536                } catch (NameNotFoundException e) {
15537                    dumpUid = -1;
15538                }
15539            }
15540            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
15541                int uid = mGrantedUriPermissions.keyAt(i);
15542                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
15543                    continue;
15544                }
15545                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
15546                if (!printed) {
15547                    if (needSep) pw.println();
15548                    needSep = true;
15549                    pw.println("  Granted Uri Permissions:");
15550                    printed = true;
15551                    printedAnything = true;
15552                }
15553                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
15554                for (UriPermission perm : perms.values()) {
15555                    pw.print("    "); pw.println(perm);
15556                    if (dumpAll) {
15557                        perm.dump(pw, "      ");
15558                    }
15559                }
15560            }
15561        }
15562
15563        if (!printedAnything) {
15564            pw.println("  (nothing)");
15565        }
15566    }
15567
15568    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15569            int opti, boolean dumpAll, String dumpPackage) {
15570        boolean printed = false;
15571
15572        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
15573
15574        if (mIntentSenderRecords.size() > 0) {
15575            Iterator<WeakReference<PendingIntentRecord>> it
15576                    = mIntentSenderRecords.values().iterator();
15577            while (it.hasNext()) {
15578                WeakReference<PendingIntentRecord> ref = it.next();
15579                PendingIntentRecord rec = ref != null ? ref.get(): null;
15580                if (dumpPackage != null && (rec == null
15581                        || !dumpPackage.equals(rec.key.packageName))) {
15582                    continue;
15583                }
15584                printed = true;
15585                if (rec != null) {
15586                    pw.print("  * "); pw.println(rec);
15587                    if (dumpAll) {
15588                        rec.dump(pw, "    ");
15589                    }
15590                } else {
15591                    pw.print("  * "); pw.println(ref);
15592                }
15593            }
15594        }
15595
15596        if (!printed) {
15597            pw.println("  (nothing)");
15598        }
15599    }
15600
15601    private static final int dumpProcessList(PrintWriter pw,
15602            ActivityManagerService service, List list,
15603            String prefix, String normalLabel, String persistentLabel,
15604            String dumpPackage) {
15605        int numPers = 0;
15606        final int N = list.size()-1;
15607        for (int i=N; i>=0; i--) {
15608            ProcessRecord r = (ProcessRecord)list.get(i);
15609            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15610                continue;
15611            }
15612            pw.println(String.format("%s%s #%2d: %s",
15613                    prefix, (r.persistent ? persistentLabel : normalLabel),
15614                    i, r.toString()));
15615            if (r.persistent) {
15616                numPers++;
15617            }
15618        }
15619        return numPers;
15620    }
15621
15622    private static final boolean dumpProcessOomList(PrintWriter pw,
15623            ActivityManagerService service, List<ProcessRecord> origList,
15624            String prefix, String normalLabel, String persistentLabel,
15625            boolean inclDetails, String dumpPackage) {
15626
15627        ArrayList<Pair<ProcessRecord, Integer>> list
15628                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15629        for (int i=0; i<origList.size(); i++) {
15630            ProcessRecord r = origList.get(i);
15631            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15632                continue;
15633            }
15634            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15635        }
15636
15637        if (list.size() <= 0) {
15638            return false;
15639        }
15640
15641        Comparator<Pair<ProcessRecord, Integer>> comparator
15642                = new Comparator<Pair<ProcessRecord, Integer>>() {
15643            @Override
15644            public int compare(Pair<ProcessRecord, Integer> object1,
15645                    Pair<ProcessRecord, Integer> object2) {
15646                if (object1.first.setAdj != object2.first.setAdj) {
15647                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15648                }
15649                if (object1.first.setProcState != object2.first.setProcState) {
15650                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15651                }
15652                if (object1.second.intValue() != object2.second.intValue()) {
15653                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15654                }
15655                return 0;
15656            }
15657        };
15658
15659        Collections.sort(list, comparator);
15660
15661        final long curRealtime = SystemClock.elapsedRealtime();
15662        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15663        final long curUptime = SystemClock.uptimeMillis();
15664        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15665
15666        for (int i=list.size()-1; i>=0; i--) {
15667            ProcessRecord r = list.get(i).first;
15668            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15669            char schedGroup;
15670            switch (r.setSchedGroup) {
15671                case ProcessList.SCHED_GROUP_BACKGROUND:
15672                    schedGroup = 'B';
15673                    break;
15674                case ProcessList.SCHED_GROUP_DEFAULT:
15675                    schedGroup = 'F';
15676                    break;
15677                case ProcessList.SCHED_GROUP_TOP_APP:
15678                    schedGroup = 'T';
15679                    break;
15680                default:
15681                    schedGroup = '?';
15682                    break;
15683            }
15684            char foreground;
15685            if (r.foregroundActivities) {
15686                foreground = 'A';
15687            } else if (r.foregroundServices) {
15688                foreground = 'S';
15689            } else {
15690                foreground = ' ';
15691            }
15692            String procState = ProcessList.makeProcStateString(r.curProcState);
15693            pw.print(prefix);
15694            pw.print(r.persistent ? persistentLabel : normalLabel);
15695            pw.print(" #");
15696            int num = (origList.size()-1)-list.get(i).second;
15697            if (num < 10) pw.print(' ');
15698            pw.print(num);
15699            pw.print(": ");
15700            pw.print(oomAdj);
15701            pw.print(' ');
15702            pw.print(schedGroup);
15703            pw.print('/');
15704            pw.print(foreground);
15705            pw.print('/');
15706            pw.print(procState);
15707            pw.print(" trm:");
15708            if (r.trimMemoryLevel < 10) pw.print(' ');
15709            pw.print(r.trimMemoryLevel);
15710            pw.print(' ');
15711            pw.print(r.toShortString());
15712            pw.print(" (");
15713            pw.print(r.adjType);
15714            pw.println(')');
15715            if (r.adjSource != null || r.adjTarget != null) {
15716                pw.print(prefix);
15717                pw.print("    ");
15718                if (r.adjTarget instanceof ComponentName) {
15719                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15720                } else if (r.adjTarget != null) {
15721                    pw.print(r.adjTarget.toString());
15722                } else {
15723                    pw.print("{null}");
15724                }
15725                pw.print("<=");
15726                if (r.adjSource instanceof ProcessRecord) {
15727                    pw.print("Proc{");
15728                    pw.print(((ProcessRecord)r.adjSource).toShortString());
15729                    pw.println("}");
15730                } else if (r.adjSource != null) {
15731                    pw.println(r.adjSource.toString());
15732                } else {
15733                    pw.println("{null}");
15734                }
15735            }
15736            if (inclDetails) {
15737                pw.print(prefix);
15738                pw.print("    ");
15739                pw.print("oom: max="); pw.print(r.maxAdj);
15740                pw.print(" curRaw="); pw.print(r.curRawAdj);
15741                pw.print(" setRaw="); pw.print(r.setRawAdj);
15742                pw.print(" cur="); pw.print(r.curAdj);
15743                pw.print(" set="); pw.println(r.setAdj);
15744                pw.print(prefix);
15745                pw.print("    ");
15746                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15747                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15748                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15749                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15750                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15751                pw.println();
15752                pw.print(prefix);
15753                pw.print("    ");
15754                pw.print("cached="); pw.print(r.cached);
15755                pw.print(" empty="); pw.print(r.empty);
15756                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15757
15758                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15759                    if (r.lastWakeTime != 0) {
15760                        long wtime;
15761                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15762                        synchronized (stats) {
15763                            wtime = stats.getProcessWakeTime(r.info.uid,
15764                                    r.pid, curRealtime);
15765                        }
15766                        long timeUsed = wtime - r.lastWakeTime;
15767                        pw.print(prefix);
15768                        pw.print("    ");
15769                        pw.print("keep awake over ");
15770                        TimeUtils.formatDuration(realtimeSince, pw);
15771                        pw.print(" used ");
15772                        TimeUtils.formatDuration(timeUsed, pw);
15773                        pw.print(" (");
15774                        pw.print((timeUsed*100)/realtimeSince);
15775                        pw.println("%)");
15776                    }
15777                    if (r.lastCpuTime != 0) {
15778                        long timeUsed = r.curCpuTime - r.lastCpuTime;
15779                        pw.print(prefix);
15780                        pw.print("    ");
15781                        pw.print("run cpu over ");
15782                        TimeUtils.formatDuration(uptimeSince, pw);
15783                        pw.print(" used ");
15784                        TimeUtils.formatDuration(timeUsed, pw);
15785                        pw.print(" (");
15786                        pw.print((timeUsed*100)/uptimeSince);
15787                        pw.println("%)");
15788                    }
15789                }
15790            }
15791        }
15792        return true;
15793    }
15794
15795    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15796            String[] args) {
15797        ArrayList<ProcessRecord> procs;
15798        synchronized (this) {
15799            if (args != null && args.length > start
15800                    && args[start].charAt(0) != '-') {
15801                procs = new ArrayList<ProcessRecord>();
15802                int pid = -1;
15803                try {
15804                    pid = Integer.parseInt(args[start]);
15805                } catch (NumberFormatException e) {
15806                }
15807                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15808                    ProcessRecord proc = mLruProcesses.get(i);
15809                    if (proc.pid == pid) {
15810                        procs.add(proc);
15811                    } else if (allPkgs && proc.pkgList != null
15812                            && proc.pkgList.containsKey(args[start])) {
15813                        procs.add(proc);
15814                    } else if (proc.processName.equals(args[start])) {
15815                        procs.add(proc);
15816                    }
15817                }
15818                if (procs.size() <= 0) {
15819                    return null;
15820                }
15821            } else {
15822                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15823            }
15824        }
15825        return procs;
15826    }
15827
15828    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15829            PrintWriter pw, String[] args) {
15830        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15831        if (procs == null) {
15832            pw.println("No process found for: " + args[0]);
15833            return;
15834        }
15835
15836        long uptime = SystemClock.uptimeMillis();
15837        long realtime = SystemClock.elapsedRealtime();
15838        pw.println("Applications Graphics Acceleration Info:");
15839        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15840
15841        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15842            ProcessRecord r = procs.get(i);
15843            if (r.thread != null) {
15844                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15845                pw.flush();
15846                try {
15847                    TransferPipe tp = new TransferPipe();
15848                    try {
15849                        r.thread.dumpGfxInfo(tp.getWriteFd(), args);
15850                        tp.go(fd);
15851                    } finally {
15852                        tp.kill();
15853                    }
15854                } catch (IOException e) {
15855                    pw.println("Failure while dumping the app: " + r);
15856                    pw.flush();
15857                } catch (RemoteException e) {
15858                    pw.println("Got a RemoteException while dumping the app " + r);
15859                    pw.flush();
15860                }
15861            }
15862        }
15863    }
15864
15865    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15866        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15867        if (procs == null) {
15868            pw.println("No process found for: " + args[0]);
15869            return;
15870        }
15871
15872        pw.println("Applications Database Info:");
15873
15874        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15875            ProcessRecord r = procs.get(i);
15876            if (r.thread != null) {
15877                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15878                pw.flush();
15879                try {
15880                    TransferPipe tp = new TransferPipe();
15881                    try {
15882                        r.thread.dumpDbInfo(tp.getWriteFd(), args);
15883                        tp.go(fd);
15884                    } finally {
15885                        tp.kill();
15886                    }
15887                } catch (IOException e) {
15888                    pw.println("Failure while dumping the app: " + r);
15889                    pw.flush();
15890                } catch (RemoteException e) {
15891                    pw.println("Got a RemoteException while dumping the app " + r);
15892                    pw.flush();
15893                }
15894            }
15895        }
15896    }
15897
15898    final static class MemItem {
15899        final boolean isProc;
15900        final String label;
15901        final String shortLabel;
15902        final long pss;
15903        final long swapPss;
15904        final int id;
15905        final boolean hasActivities;
15906        ArrayList<MemItem> subitems;
15907
15908        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15909                boolean _hasActivities) {
15910            isProc = true;
15911            label = _label;
15912            shortLabel = _shortLabel;
15913            pss = _pss;
15914            swapPss = _swapPss;
15915            id = _id;
15916            hasActivities = _hasActivities;
15917        }
15918
15919        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15920            isProc = false;
15921            label = _label;
15922            shortLabel = _shortLabel;
15923            pss = _pss;
15924            swapPss = _swapPss;
15925            id = _id;
15926            hasActivities = false;
15927        }
15928    }
15929
15930    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15931            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15932        if (sort && !isCompact) {
15933            Collections.sort(items, new Comparator<MemItem>() {
15934                @Override
15935                public int compare(MemItem lhs, MemItem rhs) {
15936                    if (lhs.pss < rhs.pss) {
15937                        return 1;
15938                    } else if (lhs.pss > rhs.pss) {
15939                        return -1;
15940                    }
15941                    return 0;
15942                }
15943            });
15944        }
15945
15946        for (int i=0; i<items.size(); i++) {
15947            MemItem mi = items.get(i);
15948            if (!isCompact) {
15949                if (dumpSwapPss) {
15950                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15951                            mi.label, stringifyKBSize(mi.swapPss));
15952                } else {
15953                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15954                }
15955            } else if (mi.isProc) {
15956                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15957                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15958                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15959                pw.println(mi.hasActivities ? ",a" : ",e");
15960            } else {
15961                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15962                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15963            }
15964            if (mi.subitems != null) {
15965                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15966                        true, isCompact, dumpSwapPss);
15967            }
15968        }
15969    }
15970
15971    // These are in KB.
15972    static final long[] DUMP_MEM_BUCKETS = new long[] {
15973        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15974        120*1024, 160*1024, 200*1024,
15975        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15976        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15977    };
15978
15979    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15980            boolean stackLike) {
15981        int start = label.lastIndexOf('.');
15982        if (start >= 0) start++;
15983        else start = 0;
15984        int end = label.length();
15985        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15986            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15987                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15988                out.append(bucket);
15989                out.append(stackLike ? "MB." : "MB ");
15990                out.append(label, start, end);
15991                return;
15992            }
15993        }
15994        out.append(memKB/1024);
15995        out.append(stackLike ? "MB." : "MB ");
15996        out.append(label, start, end);
15997    }
15998
15999    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
16000            ProcessList.NATIVE_ADJ,
16001            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
16002            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
16003            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
16004            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
16005            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
16006            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
16007    };
16008    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
16009            "Native",
16010            "System", "Persistent", "Persistent Service", "Foreground",
16011            "Visible", "Perceptible",
16012            "Heavy Weight", "Backup",
16013            "A Services", "Home",
16014            "Previous", "B Services", "Cached"
16015    };
16016    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
16017            "native",
16018            "sys", "pers", "persvc", "fore",
16019            "vis", "percept",
16020            "heavy", "backup",
16021            "servicea", "home",
16022            "prev", "serviceb", "cached"
16023    };
16024
16025    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
16026            long realtime, boolean isCheckinRequest, boolean isCompact) {
16027        if (isCompact) {
16028            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
16029        }
16030        if (isCheckinRequest || isCompact) {
16031            // short checkin version
16032            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
16033        } else {
16034            pw.println("Applications Memory Usage (in Kilobytes):");
16035            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
16036        }
16037    }
16038
16039    private static final int KSM_SHARED = 0;
16040    private static final int KSM_SHARING = 1;
16041    private static final int KSM_UNSHARED = 2;
16042    private static final int KSM_VOLATILE = 3;
16043
16044    private final long[] getKsmInfo() {
16045        long[] longOut = new long[4];
16046        final int[] SINGLE_LONG_FORMAT = new int[] {
16047            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
16048        };
16049        long[] longTmp = new long[1];
16050        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
16051                SINGLE_LONG_FORMAT, null, longTmp, null);
16052        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16053        longTmp[0] = 0;
16054        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
16055                SINGLE_LONG_FORMAT, null, longTmp, null);
16056        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16057        longTmp[0] = 0;
16058        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
16059                SINGLE_LONG_FORMAT, null, longTmp, null);
16060        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16061        longTmp[0] = 0;
16062        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
16063                SINGLE_LONG_FORMAT, null, longTmp, null);
16064        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16065        return longOut;
16066    }
16067
16068    private static String stringifySize(long size, int order) {
16069        Locale locale = Locale.US;
16070        switch (order) {
16071            case 1:
16072                return String.format(locale, "%,13d", size);
16073            case 1024:
16074                return String.format(locale, "%,9dK", size / 1024);
16075            case 1024 * 1024:
16076                return String.format(locale, "%,5dM", size / 1024 / 1024);
16077            case 1024 * 1024 * 1024:
16078                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
16079            default:
16080                throw new IllegalArgumentException("Invalid size order");
16081        }
16082    }
16083
16084    private static String stringifyKBSize(long size) {
16085        return stringifySize(size * 1024, 1024);
16086    }
16087
16088    // Update this version number in case you change the 'compact' format
16089    private static final int MEMINFO_COMPACT_VERSION = 1;
16090
16091    final void dumpApplicationMemoryUsage(FileDescriptor fd,
16092            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
16093        boolean dumpDetails = false;
16094        boolean dumpFullDetails = false;
16095        boolean dumpDalvik = false;
16096        boolean dumpSummaryOnly = false;
16097        boolean dumpUnreachable = false;
16098        boolean oomOnly = false;
16099        boolean isCompact = false;
16100        boolean localOnly = false;
16101        boolean packages = false;
16102        boolean isCheckinRequest = false;
16103        boolean dumpSwapPss = false;
16104
16105        int opti = 0;
16106        while (opti < args.length) {
16107            String opt = args[opti];
16108            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
16109                break;
16110            }
16111            opti++;
16112            if ("-a".equals(opt)) {
16113                dumpDetails = true;
16114                dumpFullDetails = true;
16115                dumpDalvik = true;
16116                dumpSwapPss = true;
16117            } else if ("-d".equals(opt)) {
16118                dumpDalvik = true;
16119            } else if ("-c".equals(opt)) {
16120                isCompact = true;
16121            } else if ("-s".equals(opt)) {
16122                dumpDetails = true;
16123                dumpSummaryOnly = true;
16124            } else if ("-S".equals(opt)) {
16125                dumpSwapPss = true;
16126            } else if ("--unreachable".equals(opt)) {
16127                dumpUnreachable = true;
16128            } else if ("--oom".equals(opt)) {
16129                oomOnly = true;
16130            } else if ("--local".equals(opt)) {
16131                localOnly = true;
16132            } else if ("--package".equals(opt)) {
16133                packages = true;
16134            } else if ("--checkin".equals(opt)) {
16135                isCheckinRequest = true;
16136
16137            } else if ("-h".equals(opt)) {
16138                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
16139                pw.println("  -a: include all available information for each process.");
16140                pw.println("  -d: include dalvik details.");
16141                pw.println("  -c: dump in a compact machine-parseable representation.");
16142                pw.println("  -s: dump only summary of application memory usage.");
16143                pw.println("  -S: dump also SwapPss.");
16144                pw.println("  --oom: only show processes organized by oom adj.");
16145                pw.println("  --local: only collect details locally, don't call process.");
16146                pw.println("  --package: interpret process arg as package, dumping all");
16147                pw.println("             processes that have loaded that package.");
16148                pw.println("  --checkin: dump data for a checkin");
16149                pw.println("If [process] is specified it can be the name or ");
16150                pw.println("pid of a specific process to dump.");
16151                return;
16152            } else {
16153                pw.println("Unknown argument: " + opt + "; use -h for help");
16154            }
16155        }
16156
16157        long uptime = SystemClock.uptimeMillis();
16158        long realtime = SystemClock.elapsedRealtime();
16159        final long[] tmpLong = new long[1];
16160
16161        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
16162        if (procs == null) {
16163            // No Java processes.  Maybe they want to print a native process.
16164            if (args != null && args.length > opti
16165                    && args[opti].charAt(0) != '-') {
16166                ArrayList<ProcessCpuTracker.Stats> nativeProcs
16167                        = new ArrayList<ProcessCpuTracker.Stats>();
16168                updateCpuStatsNow();
16169                int findPid = -1;
16170                try {
16171                    findPid = Integer.parseInt(args[opti]);
16172                } catch (NumberFormatException e) {
16173                }
16174                synchronized (mProcessCpuTracker) {
16175                    final int N = mProcessCpuTracker.countStats();
16176                    for (int i=0; i<N; i++) {
16177                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16178                        if (st.pid == findPid || (st.baseName != null
16179                                && st.baseName.equals(args[opti]))) {
16180                            nativeProcs.add(st);
16181                        }
16182                    }
16183                }
16184                if (nativeProcs.size() > 0) {
16185                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
16186                            isCompact);
16187                    Debug.MemoryInfo mi = null;
16188                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
16189                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
16190                        final int pid = r.pid;
16191                        if (!isCheckinRequest && dumpDetails) {
16192                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
16193                        }
16194                        if (mi == null) {
16195                            mi = new Debug.MemoryInfo();
16196                        }
16197                        if (dumpDetails || (!brief && !oomOnly)) {
16198                            Debug.getMemoryInfo(pid, mi);
16199                        } else {
16200                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16201                            mi.dalvikPrivateDirty = (int)tmpLong[0];
16202                        }
16203                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16204                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
16205                        if (isCheckinRequest) {
16206                            pw.println();
16207                        }
16208                    }
16209                    return;
16210                }
16211            }
16212            pw.println("No process found for: " + args[opti]);
16213            return;
16214        }
16215
16216        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
16217            dumpDetails = true;
16218        }
16219
16220        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
16221
16222        String[] innerArgs = new String[args.length-opti];
16223        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
16224
16225        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
16226        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
16227        long nativePss = 0;
16228        long nativeSwapPss = 0;
16229        long dalvikPss = 0;
16230        long dalvikSwapPss = 0;
16231        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16232                EmptyArray.LONG;
16233        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16234                EmptyArray.LONG;
16235        long otherPss = 0;
16236        long otherSwapPss = 0;
16237        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16238        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16239
16240        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16241        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16242        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
16243                new ArrayList[DUMP_MEM_OOM_LABEL.length];
16244
16245        long totalPss = 0;
16246        long totalSwapPss = 0;
16247        long cachedPss = 0;
16248        long cachedSwapPss = 0;
16249        boolean hasSwapPss = false;
16250
16251        Debug.MemoryInfo mi = null;
16252        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16253            final ProcessRecord r = procs.get(i);
16254            final IApplicationThread thread;
16255            final int pid;
16256            final int oomAdj;
16257            final boolean hasActivities;
16258            synchronized (this) {
16259                thread = r.thread;
16260                pid = r.pid;
16261                oomAdj = r.getSetAdjWithServices();
16262                hasActivities = r.activities.size() > 0;
16263            }
16264            if (thread != null) {
16265                if (!isCheckinRequest && dumpDetails) {
16266                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
16267                }
16268                if (mi == null) {
16269                    mi = new Debug.MemoryInfo();
16270                }
16271                if (dumpDetails || (!brief && !oomOnly)) {
16272                    Debug.getMemoryInfo(pid, mi);
16273                    hasSwapPss = mi.hasSwappedOutPss;
16274                } else {
16275                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16276                    mi.dalvikPrivateDirty = (int)tmpLong[0];
16277                }
16278                if (dumpDetails) {
16279                    if (localOnly) {
16280                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16281                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
16282                        if (isCheckinRequest) {
16283                            pw.println();
16284                        }
16285                    } else {
16286                        pw.flush();
16287                        try {
16288                            TransferPipe tp = new TransferPipe();
16289                            try {
16290                                thread.dumpMemInfo(tp.getWriteFd(),
16291                                        mi, isCheckinRequest, dumpFullDetails,
16292                                        dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
16293                                tp.go(fd);
16294                            } finally {
16295                                tp.kill();
16296                            }
16297                        } catch (IOException e) {
16298                            if (!isCheckinRequest) {
16299                                pw.println("Got IoException!");
16300                                pw.flush();
16301                            }
16302                        } catch (RemoteException e) {
16303                            if (!isCheckinRequest) {
16304                                pw.println("Got RemoteException!");
16305                                pw.flush();
16306                            }
16307                        }
16308                    }
16309                }
16310
16311                final long myTotalPss = mi.getTotalPss();
16312                final long myTotalUss = mi.getTotalUss();
16313                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16314
16315                synchronized (this) {
16316                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
16317                        // Record this for posterity if the process has been stable.
16318                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
16319                    }
16320                }
16321
16322                if (!isCheckinRequest && mi != null) {
16323                    totalPss += myTotalPss;
16324                    totalSwapPss += myTotalSwapPss;
16325                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
16326                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
16327                            myTotalSwapPss, pid, hasActivities);
16328                    procMems.add(pssItem);
16329                    procMemsMap.put(pid, pssItem);
16330
16331                    nativePss += mi.nativePss;
16332                    nativeSwapPss += mi.nativeSwappedOutPss;
16333                    dalvikPss += mi.dalvikPss;
16334                    dalvikSwapPss += mi.dalvikSwappedOutPss;
16335                    for (int j=0; j<dalvikSubitemPss.length; j++) {
16336                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16337                        dalvikSubitemSwapPss[j] +=
16338                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16339                    }
16340                    otherPss += mi.otherPss;
16341                    otherSwapPss += mi.otherSwappedOutPss;
16342                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16343                        long mem = mi.getOtherPss(j);
16344                        miscPss[j] += mem;
16345                        otherPss -= mem;
16346                        mem = mi.getOtherSwappedOutPss(j);
16347                        miscSwapPss[j] += mem;
16348                        otherSwapPss -= mem;
16349                    }
16350
16351                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16352                        cachedPss += myTotalPss;
16353                        cachedSwapPss += myTotalSwapPss;
16354                    }
16355
16356                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
16357                        if (oomIndex == (oomPss.length - 1)
16358                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
16359                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
16360                            oomPss[oomIndex] += myTotalPss;
16361                            oomSwapPss[oomIndex] += myTotalSwapPss;
16362                            if (oomProcs[oomIndex] == null) {
16363                                oomProcs[oomIndex] = new ArrayList<MemItem>();
16364                            }
16365                            oomProcs[oomIndex].add(pssItem);
16366                            break;
16367                        }
16368                    }
16369                }
16370            }
16371        }
16372
16373        long nativeProcTotalPss = 0;
16374
16375        if (!isCheckinRequest && procs.size() > 1 && !packages) {
16376            // If we are showing aggregations, also look for native processes to
16377            // include so that our aggregations are more accurate.
16378            updateCpuStatsNow();
16379            mi = null;
16380            synchronized (mProcessCpuTracker) {
16381                final int N = mProcessCpuTracker.countStats();
16382                for (int i=0; i<N; i++) {
16383                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16384                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
16385                        if (mi == null) {
16386                            mi = new Debug.MemoryInfo();
16387                        }
16388                        if (!brief && !oomOnly) {
16389                            Debug.getMemoryInfo(st.pid, mi);
16390                        } else {
16391                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
16392                            mi.nativePrivateDirty = (int)tmpLong[0];
16393                        }
16394
16395                        final long myTotalPss = mi.getTotalPss();
16396                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16397                        totalPss += myTotalPss;
16398                        nativeProcTotalPss += myTotalPss;
16399
16400                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
16401                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
16402                        procMems.add(pssItem);
16403
16404                        nativePss += mi.nativePss;
16405                        nativeSwapPss += mi.nativeSwappedOutPss;
16406                        dalvikPss += mi.dalvikPss;
16407                        dalvikSwapPss += mi.dalvikSwappedOutPss;
16408                        for (int j=0; j<dalvikSubitemPss.length; j++) {
16409                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16410                            dalvikSubitemSwapPss[j] +=
16411                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16412                        }
16413                        otherPss += mi.otherPss;
16414                        otherSwapPss += mi.otherSwappedOutPss;
16415                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16416                            long mem = mi.getOtherPss(j);
16417                            miscPss[j] += mem;
16418                            otherPss -= mem;
16419                            mem = mi.getOtherSwappedOutPss(j);
16420                            miscSwapPss[j] += mem;
16421                            otherSwapPss -= mem;
16422                        }
16423                        oomPss[0] += myTotalPss;
16424                        oomSwapPss[0] += myTotalSwapPss;
16425                        if (oomProcs[0] == null) {
16426                            oomProcs[0] = new ArrayList<MemItem>();
16427                        }
16428                        oomProcs[0].add(pssItem);
16429                    }
16430                }
16431            }
16432
16433            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
16434
16435            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
16436            final MemItem dalvikItem =
16437                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
16438            if (dalvikSubitemPss.length > 0) {
16439                dalvikItem.subitems = new ArrayList<MemItem>();
16440                for (int j=0; j<dalvikSubitemPss.length; j++) {
16441                    final String name = Debug.MemoryInfo.getOtherLabel(
16442                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
16443                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
16444                                    dalvikSubitemSwapPss[j], j));
16445                }
16446            }
16447            catMems.add(dalvikItem);
16448            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
16449            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16450                String label = Debug.MemoryInfo.getOtherLabel(j);
16451                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
16452            }
16453
16454            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
16455            for (int j=0; j<oomPss.length; j++) {
16456                if (oomPss[j] != 0) {
16457                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
16458                            : DUMP_MEM_OOM_LABEL[j];
16459                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
16460                            DUMP_MEM_OOM_ADJ[j]);
16461                    item.subitems = oomProcs[j];
16462                    oomMems.add(item);
16463                }
16464            }
16465
16466            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
16467            if (!brief && !oomOnly && !isCompact) {
16468                pw.println();
16469                pw.println("Total PSS by process:");
16470                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
16471                pw.println();
16472            }
16473            if (!isCompact) {
16474                pw.println("Total PSS by OOM adjustment:");
16475            }
16476            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
16477            if (!brief && !oomOnly) {
16478                PrintWriter out = categoryPw != null ? categoryPw : pw;
16479                if (!isCompact) {
16480                    out.println();
16481                    out.println("Total PSS by category:");
16482                }
16483                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
16484            }
16485            if (!isCompact) {
16486                pw.println();
16487            }
16488            MemInfoReader memInfo = new MemInfoReader();
16489            memInfo.readMemInfo();
16490            if (nativeProcTotalPss > 0) {
16491                synchronized (this) {
16492                    final long cachedKb = memInfo.getCachedSizeKb();
16493                    final long freeKb = memInfo.getFreeSizeKb();
16494                    final long zramKb = memInfo.getZramTotalSizeKb();
16495                    final long kernelKb = memInfo.getKernelUsedSizeKb();
16496                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
16497                            kernelKb*1024, nativeProcTotalPss*1024);
16498                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
16499                            nativeProcTotalPss);
16500                }
16501            }
16502            if (!brief) {
16503                if (!isCompact) {
16504                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
16505                    pw.print(" (status ");
16506                    switch (mLastMemoryLevel) {
16507                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
16508                            pw.println("normal)");
16509                            break;
16510                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
16511                            pw.println("moderate)");
16512                            break;
16513                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
16514                            pw.println("low)");
16515                            break;
16516                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16517                            pw.println("critical)");
16518                            break;
16519                        default:
16520                            pw.print(mLastMemoryLevel);
16521                            pw.println(")");
16522                            break;
16523                    }
16524                    pw.print(" Free RAM: ");
16525                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16526                            + memInfo.getFreeSizeKb()));
16527                    pw.print(" (");
16528                    pw.print(stringifyKBSize(cachedPss));
16529                    pw.print(" cached pss + ");
16530                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
16531                    pw.print(" cached kernel + ");
16532                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
16533                    pw.println(" free)");
16534                } else {
16535                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
16536                    pw.print(cachedPss + memInfo.getCachedSizeKb()
16537                            + memInfo.getFreeSizeKb()); pw.print(",");
16538                    pw.println(totalPss - cachedPss);
16539                }
16540            }
16541            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
16542                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16543                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
16544            if (!isCompact) {
16545                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
16546                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
16547                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
16548                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
16549                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
16550            } else {
16551                pw.print("lostram,"); pw.println(lostRAM);
16552            }
16553            if (!brief) {
16554                if (memInfo.getZramTotalSizeKb() != 0) {
16555                    if (!isCompact) {
16556                        pw.print("     ZRAM: ");
16557                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
16558                                pw.print(" physical used for ");
16559                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
16560                                        - memInfo.getSwapFreeSizeKb()));
16561                                pw.print(" in swap (");
16562                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
16563                                pw.println(" total swap)");
16564                    } else {
16565                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
16566                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
16567                                pw.println(memInfo.getSwapFreeSizeKb());
16568                    }
16569                }
16570                final long[] ksm = getKsmInfo();
16571                if (!isCompact) {
16572                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16573                            || ksm[KSM_VOLATILE] != 0) {
16574                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
16575                                pw.print(" saved from shared ");
16576                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
16577                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
16578                                pw.print(" unshared; ");
16579                                pw.print(stringifyKBSize(
16580                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
16581                    }
16582                    pw.print("   Tuning: ");
16583                    pw.print(ActivityManager.staticGetMemoryClass());
16584                    pw.print(" (large ");
16585                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16586                    pw.print("), oom ");
16587                    pw.print(stringifySize(
16588                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
16589                    pw.print(", restore limit ");
16590                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
16591                    if (ActivityManager.isLowRamDeviceStatic()) {
16592                        pw.print(" (low-ram)");
16593                    }
16594                    if (ActivityManager.isHighEndGfx()) {
16595                        pw.print(" (high-end-gfx)");
16596                    }
16597                    pw.println();
16598                } else {
16599                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16600                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16601                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16602                    pw.print("tuning,");
16603                    pw.print(ActivityManager.staticGetMemoryClass());
16604                    pw.print(',');
16605                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16606                    pw.print(',');
16607                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16608                    if (ActivityManager.isLowRamDeviceStatic()) {
16609                        pw.print(",low-ram");
16610                    }
16611                    if (ActivityManager.isHighEndGfx()) {
16612                        pw.print(",high-end-gfx");
16613                    }
16614                    pw.println();
16615                }
16616            }
16617        }
16618    }
16619
16620    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16621            long memtrack, String name) {
16622        sb.append("  ");
16623        sb.append(ProcessList.makeOomAdjString(oomAdj));
16624        sb.append(' ');
16625        sb.append(ProcessList.makeProcStateString(procState));
16626        sb.append(' ');
16627        ProcessList.appendRamKb(sb, pss);
16628        sb.append(": ");
16629        sb.append(name);
16630        if (memtrack > 0) {
16631            sb.append(" (");
16632            sb.append(stringifyKBSize(memtrack));
16633            sb.append(" memtrack)");
16634        }
16635    }
16636
16637    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16638        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16639        sb.append(" (pid ");
16640        sb.append(mi.pid);
16641        sb.append(") ");
16642        sb.append(mi.adjType);
16643        sb.append('\n');
16644        if (mi.adjReason != null) {
16645            sb.append("                      ");
16646            sb.append(mi.adjReason);
16647            sb.append('\n');
16648        }
16649    }
16650
16651    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16652        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16653        for (int i=0, N=memInfos.size(); i<N; i++) {
16654            ProcessMemInfo mi = memInfos.get(i);
16655            infoMap.put(mi.pid, mi);
16656        }
16657        updateCpuStatsNow();
16658        long[] memtrackTmp = new long[1];
16659        final List<ProcessCpuTracker.Stats> stats;
16660        // Get a list of Stats that have vsize > 0
16661        synchronized (mProcessCpuTracker) {
16662            stats = mProcessCpuTracker.getStats((st) -> {
16663                return st.vsize > 0;
16664            });
16665        }
16666        final int statsCount = stats.size();
16667        for (int i = 0; i < statsCount; i++) {
16668            ProcessCpuTracker.Stats st = stats.get(i);
16669            long pss = Debug.getPss(st.pid, null, memtrackTmp);
16670            if (pss > 0) {
16671                if (infoMap.indexOfKey(st.pid) < 0) {
16672                    ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16673                            ProcessList.NATIVE_ADJ, -1, "native", null);
16674                    mi.pss = pss;
16675                    mi.memtrack = memtrackTmp[0];
16676                    memInfos.add(mi);
16677                }
16678            }
16679        }
16680
16681        long totalPss = 0;
16682        long totalMemtrack = 0;
16683        for (int i=0, N=memInfos.size(); i<N; i++) {
16684            ProcessMemInfo mi = memInfos.get(i);
16685            if (mi.pss == 0) {
16686                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16687                mi.memtrack = memtrackTmp[0];
16688            }
16689            totalPss += mi.pss;
16690            totalMemtrack += mi.memtrack;
16691        }
16692        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16693            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16694                if (lhs.oomAdj != rhs.oomAdj) {
16695                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16696                }
16697                if (lhs.pss != rhs.pss) {
16698                    return lhs.pss < rhs.pss ? 1 : -1;
16699                }
16700                return 0;
16701            }
16702        });
16703
16704        StringBuilder tag = new StringBuilder(128);
16705        StringBuilder stack = new StringBuilder(128);
16706        tag.append("Low on memory -- ");
16707        appendMemBucket(tag, totalPss, "total", false);
16708        appendMemBucket(stack, totalPss, "total", true);
16709
16710        StringBuilder fullNativeBuilder = new StringBuilder(1024);
16711        StringBuilder shortNativeBuilder = new StringBuilder(1024);
16712        StringBuilder fullJavaBuilder = new StringBuilder(1024);
16713
16714        boolean firstLine = true;
16715        int lastOomAdj = Integer.MIN_VALUE;
16716        long extraNativeRam = 0;
16717        long extraNativeMemtrack = 0;
16718        long cachedPss = 0;
16719        for (int i=0, N=memInfos.size(); i<N; i++) {
16720            ProcessMemInfo mi = memInfos.get(i);
16721
16722            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16723                cachedPss += mi.pss;
16724            }
16725
16726            if (mi.oomAdj != ProcessList.NATIVE_ADJ
16727                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
16728                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
16729                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16730                if (lastOomAdj != mi.oomAdj) {
16731                    lastOomAdj = mi.oomAdj;
16732                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16733                        tag.append(" / ");
16734                    }
16735                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16736                        if (firstLine) {
16737                            stack.append(":");
16738                            firstLine = false;
16739                        }
16740                        stack.append("\n\t at ");
16741                    } else {
16742                        stack.append("$");
16743                    }
16744                } else {
16745                    tag.append(" ");
16746                    stack.append("$");
16747                }
16748                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16749                    appendMemBucket(tag, mi.pss, mi.name, false);
16750                }
16751                appendMemBucket(stack, mi.pss, mi.name, true);
16752                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16753                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16754                    stack.append("(");
16755                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16756                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16757                            stack.append(DUMP_MEM_OOM_LABEL[k]);
16758                            stack.append(":");
16759                            stack.append(DUMP_MEM_OOM_ADJ[k]);
16760                        }
16761                    }
16762                    stack.append(")");
16763                }
16764            }
16765
16766            appendMemInfo(fullNativeBuilder, mi);
16767            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16768                // The short form only has native processes that are >= 512K.
16769                if (mi.pss >= 512) {
16770                    appendMemInfo(shortNativeBuilder, mi);
16771                } else {
16772                    extraNativeRam += mi.pss;
16773                    extraNativeMemtrack += mi.memtrack;
16774                }
16775            } else {
16776                // Short form has all other details, but if we have collected RAM
16777                // from smaller native processes let's dump a summary of that.
16778                if (extraNativeRam > 0) {
16779                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16780                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16781                    shortNativeBuilder.append('\n');
16782                    extraNativeRam = 0;
16783                }
16784                appendMemInfo(fullJavaBuilder, mi);
16785            }
16786        }
16787
16788        fullJavaBuilder.append("           ");
16789        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16790        fullJavaBuilder.append(": TOTAL");
16791        if (totalMemtrack > 0) {
16792            fullJavaBuilder.append(" (");
16793            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16794            fullJavaBuilder.append(" memtrack)");
16795        } else {
16796        }
16797        fullJavaBuilder.append("\n");
16798
16799        MemInfoReader memInfo = new MemInfoReader();
16800        memInfo.readMemInfo();
16801        final long[] infos = memInfo.getRawInfo();
16802
16803        StringBuilder memInfoBuilder = new StringBuilder(1024);
16804        Debug.getMemInfo(infos);
16805        memInfoBuilder.append("  MemInfo: ");
16806        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16807        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16808        memInfoBuilder.append(stringifyKBSize(
16809                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16810        memInfoBuilder.append(stringifyKBSize(
16811                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16812        memInfoBuilder.append(stringifyKBSize(
16813                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16814        memInfoBuilder.append("           ");
16815        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16816        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16817        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16818        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16819        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16820            memInfoBuilder.append("  ZRAM: ");
16821            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16822            memInfoBuilder.append(" RAM, ");
16823            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16824            memInfoBuilder.append(" swap total, ");
16825            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16826            memInfoBuilder.append(" swap free\n");
16827        }
16828        final long[] ksm = getKsmInfo();
16829        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16830                || ksm[KSM_VOLATILE] != 0) {
16831            memInfoBuilder.append("  KSM: ");
16832            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16833            memInfoBuilder.append(" saved from shared ");
16834            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16835            memInfoBuilder.append("\n       ");
16836            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16837            memInfoBuilder.append(" unshared; ");
16838            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16839            memInfoBuilder.append(" volatile\n");
16840        }
16841        memInfoBuilder.append("  Free RAM: ");
16842        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16843                + memInfo.getFreeSizeKb()));
16844        memInfoBuilder.append("\n");
16845        memInfoBuilder.append("  Used RAM: ");
16846        memInfoBuilder.append(stringifyKBSize(
16847                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16848        memInfoBuilder.append("\n");
16849        memInfoBuilder.append("  Lost RAM: ");
16850        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16851                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16852                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16853        memInfoBuilder.append("\n");
16854        Slog.i(TAG, "Low on memory:");
16855        Slog.i(TAG, shortNativeBuilder.toString());
16856        Slog.i(TAG, fullJavaBuilder.toString());
16857        Slog.i(TAG, memInfoBuilder.toString());
16858
16859        StringBuilder dropBuilder = new StringBuilder(1024);
16860        /*
16861        StringWriter oomSw = new StringWriter();
16862        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16863        StringWriter catSw = new StringWriter();
16864        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16865        String[] emptyArgs = new String[] { };
16866        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16867        oomPw.flush();
16868        String oomString = oomSw.toString();
16869        */
16870        dropBuilder.append("Low on memory:");
16871        dropBuilder.append(stack);
16872        dropBuilder.append('\n');
16873        dropBuilder.append(fullNativeBuilder);
16874        dropBuilder.append(fullJavaBuilder);
16875        dropBuilder.append('\n');
16876        dropBuilder.append(memInfoBuilder);
16877        dropBuilder.append('\n');
16878        /*
16879        dropBuilder.append(oomString);
16880        dropBuilder.append('\n');
16881        */
16882        StringWriter catSw = new StringWriter();
16883        synchronized (ActivityManagerService.this) {
16884            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16885            String[] emptyArgs = new String[] { };
16886            catPw.println();
16887            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16888            catPw.println();
16889            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
16890                    false, null).dumpLocked();
16891            catPw.println();
16892            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16893            catPw.flush();
16894        }
16895        dropBuilder.append(catSw.toString());
16896        addErrorToDropBox("lowmem", null, "system_server", null,
16897                null, tag.toString(), dropBuilder.toString(), null, null);
16898        //Slog.i(TAG, "Sent to dropbox:");
16899        //Slog.i(TAG, dropBuilder.toString());
16900        synchronized (ActivityManagerService.this) {
16901            long now = SystemClock.uptimeMillis();
16902            if (mLastMemUsageReportTime < now) {
16903                mLastMemUsageReportTime = now;
16904            }
16905        }
16906    }
16907
16908    /**
16909     * Searches array of arguments for the specified string
16910     * @param args array of argument strings
16911     * @param value value to search for
16912     * @return true if the value is contained in the array
16913     */
16914    private static boolean scanArgs(String[] args, String value) {
16915        if (args != null) {
16916            for (String arg : args) {
16917                if (value.equals(arg)) {
16918                    return true;
16919                }
16920            }
16921        }
16922        return false;
16923    }
16924
16925    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16926            ContentProviderRecord cpr, boolean always) {
16927        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16928
16929        if (!inLaunching || always) {
16930            synchronized (cpr) {
16931                cpr.launchingApp = null;
16932                cpr.notifyAll();
16933            }
16934            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16935            String names[] = cpr.info.authority.split(";");
16936            for (int j = 0; j < names.length; j++) {
16937                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16938            }
16939        }
16940
16941        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16942            ContentProviderConnection conn = cpr.connections.get(i);
16943            if (conn.waiting) {
16944                // If this connection is waiting for the provider, then we don't
16945                // need to mess with its process unless we are always removing
16946                // or for some reason the provider is not currently launching.
16947                if (inLaunching && !always) {
16948                    continue;
16949                }
16950            }
16951            ProcessRecord capp = conn.client;
16952            conn.dead = true;
16953            if (conn.stableCount > 0) {
16954                if (!capp.persistent && capp.thread != null
16955                        && capp.pid != 0
16956                        && capp.pid != MY_PID) {
16957                    capp.kill("depends on provider "
16958                            + cpr.name.flattenToShortString()
16959                            + " in dying proc " + (proc != null ? proc.processName : "??")
16960                            + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
16961                }
16962            } else if (capp.thread != null && conn.provider.provider != null) {
16963                try {
16964                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16965                } catch (RemoteException e) {
16966                }
16967                // In the protocol here, we don't expect the client to correctly
16968                // clean up this connection, we'll just remove it.
16969                cpr.connections.remove(i);
16970                if (conn.client.conProviders.remove(conn)) {
16971                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16972                }
16973            }
16974        }
16975
16976        if (inLaunching && always) {
16977            mLaunchingProviders.remove(cpr);
16978        }
16979        return inLaunching;
16980    }
16981
16982    /**
16983     * Main code for cleaning up a process when it has gone away.  This is
16984     * called both as a result of the process dying, or directly when stopping
16985     * a process when running in single process mode.
16986     *
16987     * @return Returns true if the given process has been restarted, so the
16988     * app that was passed in must remain on the process lists.
16989     */
16990    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16991            boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
16992        Slog.d(TAG, "cleanUpApplicationRecord -- " + app.pid);
16993        if (index >= 0) {
16994            removeLruProcessLocked(app);
16995            ProcessList.remove(app.pid);
16996        }
16997
16998        mProcessesToGc.remove(app);
16999        mPendingPssProcesses.remove(app);
17000
17001        // Dismiss any open dialogs.
17002        if (app.crashDialog != null && !app.forceCrashReport) {
17003            app.crashDialog.dismiss();
17004            app.crashDialog = null;
17005        }
17006        if (app.anrDialog != null) {
17007            app.anrDialog.dismiss();
17008            app.anrDialog = null;
17009        }
17010        if (app.waitDialog != null) {
17011            app.waitDialog.dismiss();
17012            app.waitDialog = null;
17013        }
17014
17015        app.crashing = false;
17016        app.notResponding = false;
17017
17018        app.resetPackageList(mProcessStats);
17019        app.unlinkDeathRecipient();
17020        app.makeInactive(mProcessStats);
17021        app.waitingToKill = null;
17022        app.forcingToForeground = null;
17023        updateProcessForegroundLocked(app, false, false);
17024        app.foregroundActivities = false;
17025        app.hasShownUi = false;
17026        app.treatLikeActivity = false;
17027        app.hasAboveClient = false;
17028        app.hasClientActivities = false;
17029
17030        mServices.killServicesLocked(app, allowRestart);
17031
17032        boolean restart = false;
17033
17034        // Remove published content providers.
17035        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
17036            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
17037            final boolean always = app.bad || !allowRestart;
17038            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
17039            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
17040                // We left the provider in the launching list, need to
17041                // restart it.
17042                restart = true;
17043            }
17044
17045            cpr.provider = null;
17046            cpr.proc = null;
17047        }
17048        app.pubProviders.clear();
17049
17050        // Take care of any launching providers waiting for this process.
17051        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
17052            restart = true;
17053        }
17054
17055        // Unregister from connected content providers.
17056        if (!app.conProviders.isEmpty()) {
17057            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
17058                ContentProviderConnection conn = app.conProviders.get(i);
17059                conn.provider.connections.remove(conn);
17060                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
17061                        conn.provider.name);
17062            }
17063            app.conProviders.clear();
17064        }
17065
17066        // At this point there may be remaining entries in mLaunchingProviders
17067        // where we were the only one waiting, so they are no longer of use.
17068        // Look for these and clean up if found.
17069        // XXX Commented out for now.  Trying to figure out a way to reproduce
17070        // the actual situation to identify what is actually going on.
17071        if (false) {
17072            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17073                ContentProviderRecord cpr = mLaunchingProviders.get(i);
17074                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
17075                    synchronized (cpr) {
17076                        cpr.launchingApp = null;
17077                        cpr.notifyAll();
17078                    }
17079                }
17080            }
17081        }
17082
17083        skipCurrentReceiverLocked(app);
17084
17085        // Unregister any receivers.
17086        for (int i = app.receivers.size() - 1; i >= 0; i--) {
17087            removeReceiverLocked(app.receivers.valueAt(i));
17088        }
17089        app.receivers.clear();
17090
17091        // If the app is undergoing backup, tell the backup manager about it
17092        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
17093            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
17094                    + mBackupTarget.appInfo + " died during backup");
17095            mHandler.post(new Runnable() {
17096                @Override
17097                public void run(){
17098                    try {
17099                        IBackupManager bm = IBackupManager.Stub.asInterface(
17100                                ServiceManager.getService(Context.BACKUP_SERVICE));
17101                        bm.agentDisconnected(app.info.packageName);
17102                    } catch (RemoteException e) {
17103                        // can't happen; backup manager is local
17104                    }
17105                }
17106            });
17107        }
17108
17109        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
17110            ProcessChangeItem item = mPendingProcessChanges.get(i);
17111            if (item.pid == app.pid) {
17112                mPendingProcessChanges.remove(i);
17113                mAvailProcessChanges.add(item);
17114            }
17115        }
17116        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
17117                null).sendToTarget();
17118
17119        // If the caller is restarting this app, then leave it in its
17120        // current lists and let the caller take care of it.
17121        if (restarting) {
17122            return false;
17123        }
17124
17125        if (!app.persistent || app.isolated) {
17126            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
17127                    "Removing non-persistent process during cleanup: " + app);
17128            if (!replacingPid) {
17129                removeProcessNameLocked(app.processName, app.uid, app);
17130            }
17131            if (mHeavyWeightProcess == app) {
17132                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
17133                        mHeavyWeightProcess.userId, 0));
17134                mHeavyWeightProcess = null;
17135            }
17136        } else if (!app.removed) {
17137            // This app is persistent, so we need to keep its record around.
17138            // If it is not already on the pending app list, add it there
17139            // and start a new process for it.
17140            if (mPersistentStartingProcesses.indexOf(app) < 0) {
17141                mPersistentStartingProcesses.add(app);
17142                restart = true;
17143            }
17144        }
17145        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
17146                TAG_CLEANUP, "Clean-up removing on hold: " + app);
17147        mProcessesOnHold.remove(app);
17148
17149        if (app == mHomeProcess) {
17150            mHomeProcess = null;
17151        }
17152        if (app == mPreviousProcess) {
17153            mPreviousProcess = null;
17154        }
17155
17156        if (restart && !app.isolated) {
17157            // We have components that still need to be running in the
17158            // process, so re-launch it.
17159            if (index < 0) {
17160                ProcessList.remove(app.pid);
17161            }
17162            addProcessNameLocked(app);
17163            startProcessLocked(app, "restart", app.processName);
17164            return true;
17165        } else if (app.pid > 0 && app.pid != MY_PID) {
17166            // Goodbye!
17167            boolean removed;
17168            synchronized (mPidsSelfLocked) {
17169                mPidsSelfLocked.remove(app.pid);
17170                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
17171            }
17172            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
17173            if (app.isolated) {
17174                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
17175            }
17176            app.setPid(0);
17177        }
17178        return false;
17179    }
17180
17181    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
17182        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17183            ContentProviderRecord cpr = mLaunchingProviders.get(i);
17184            if (cpr.launchingApp == app) {
17185                return true;
17186            }
17187        }
17188        return false;
17189    }
17190
17191    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
17192        // Look through the content providers we are waiting to have launched,
17193        // and if any run in this process then either schedule a restart of
17194        // the process or kill the client waiting for it if this process has
17195        // gone bad.
17196        boolean restart = false;
17197        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17198            ContentProviderRecord cpr = mLaunchingProviders.get(i);
17199            if (cpr.launchingApp == app) {
17200                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
17201                    restart = true;
17202                } else {
17203                    removeDyingProviderLocked(app, cpr, true);
17204                }
17205            }
17206        }
17207        return restart;
17208    }
17209
17210    // =========================================================
17211    // SERVICES
17212    // =========================================================
17213
17214    @Override
17215    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
17216            int flags) {
17217        enforceNotIsolatedCaller("getServices");
17218        synchronized (this) {
17219            return mServices.getRunningServiceInfoLocked(maxNum, flags);
17220        }
17221    }
17222
17223    @Override
17224    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
17225        enforceNotIsolatedCaller("getRunningServiceControlPanel");
17226        synchronized (this) {
17227            return mServices.getRunningServiceControlPanelLocked(name);
17228        }
17229    }
17230
17231    @Override
17232    public ComponentName startService(IApplicationThread caller, Intent service,
17233            String resolvedType, String callingPackage, int userId)
17234            throws TransactionTooLargeException {
17235        enforceNotIsolatedCaller("startService");
17236        // Refuse possible leaked file descriptors
17237        if (service != null && service.hasFileDescriptors() == true) {
17238            throw new IllegalArgumentException("File descriptors passed in Intent");
17239        }
17240
17241        if (callingPackage == null) {
17242            throw new IllegalArgumentException("callingPackage cannot be null");
17243        }
17244
17245        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17246                "startService: " + service + " type=" + resolvedType);
17247        synchronized(this) {
17248            final int callingPid = Binder.getCallingPid();
17249            final int callingUid = Binder.getCallingUid();
17250            final long origId = Binder.clearCallingIdentity();
17251            ComponentName res = mServices.startServiceLocked(caller, service,
17252                    resolvedType, callingPid, callingUid, callingPackage, userId);
17253            Binder.restoreCallingIdentity(origId);
17254            return res;
17255        }
17256    }
17257
17258    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
17259            String callingPackage, int userId)
17260            throws TransactionTooLargeException {
17261        synchronized(this) {
17262            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17263                    "startServiceInPackage: " + service + " type=" + resolvedType);
17264            final long origId = Binder.clearCallingIdentity();
17265            ComponentName res = mServices.startServiceLocked(null, service,
17266                    resolvedType, -1, uid, callingPackage, userId);
17267            Binder.restoreCallingIdentity(origId);
17268            return res;
17269        }
17270    }
17271
17272    @Override
17273    public int stopService(IApplicationThread caller, Intent service,
17274            String resolvedType, int userId) {
17275        enforceNotIsolatedCaller("stopService");
17276        // Refuse possible leaked file descriptors
17277        if (service != null && service.hasFileDescriptors() == true) {
17278            throw new IllegalArgumentException("File descriptors passed in Intent");
17279        }
17280
17281        synchronized(this) {
17282            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
17283        }
17284    }
17285
17286    @Override
17287    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
17288        enforceNotIsolatedCaller("peekService");
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.peekServiceLocked(service, resolvedType, callingPackage);
17300        }
17301    }
17302
17303    @Override
17304    public boolean stopServiceToken(ComponentName className, IBinder token,
17305            int startId) {
17306        synchronized(this) {
17307            return mServices.stopServiceTokenLocked(className, token, startId);
17308        }
17309    }
17310
17311    @Override
17312    public void setServiceForeground(ComponentName className, IBinder token,
17313            int id, Notification notification, int flags) {
17314        synchronized(this) {
17315            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
17316        }
17317    }
17318
17319    @Override
17320    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
17321            boolean requireFull, String name, String callerPackage) {
17322        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
17323                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
17324    }
17325
17326    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
17327            String className, int flags) {
17328        boolean result = false;
17329        // For apps that don't have pre-defined UIDs, check for permission
17330        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
17331            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17332                if (ActivityManager.checkUidPermission(
17333                        INTERACT_ACROSS_USERS,
17334                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
17335                    ComponentName comp = new ComponentName(aInfo.packageName, className);
17336                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
17337                            + " requests FLAG_SINGLE_USER, but app does not hold "
17338                            + INTERACT_ACROSS_USERS;
17339                    Slog.w(TAG, msg);
17340                    throw new SecurityException(msg);
17341                }
17342                // Permission passed
17343                result = true;
17344            }
17345        } else if ("system".equals(componentProcessName)) {
17346            result = true;
17347        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17348            // Phone app and persistent apps are allowed to export singleuser providers.
17349            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
17350                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
17351        }
17352        if (DEBUG_MU) Slog.v(TAG_MU,
17353                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
17354                + Integer.toHexString(flags) + ") = " + result);
17355        return result;
17356    }
17357
17358    /**
17359     * Checks to see if the caller is in the same app as the singleton
17360     * component, or the component is in a special app. It allows special apps
17361     * to export singleton components but prevents exporting singleton
17362     * components for regular apps.
17363     */
17364    boolean isValidSingletonCall(int callingUid, int componentUid) {
17365        int componentAppId = UserHandle.getAppId(componentUid);
17366        return UserHandle.isSameApp(callingUid, componentUid)
17367                || componentAppId == Process.SYSTEM_UID
17368                || componentAppId == Process.PHONE_UID
17369                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
17370                        == PackageManager.PERMISSION_GRANTED;
17371    }
17372
17373    public int bindService(IApplicationThread caller, IBinder token, Intent service,
17374            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
17375            int userId) throws TransactionTooLargeException {
17376        enforceNotIsolatedCaller("bindService");
17377
17378        // Refuse possible leaked file descriptors
17379        if (service != null && service.hasFileDescriptors() == true) {
17380            throw new IllegalArgumentException("File descriptors passed in Intent");
17381        }
17382
17383        if (callingPackage == null) {
17384            throw new IllegalArgumentException("callingPackage cannot be null");
17385        }
17386
17387        synchronized(this) {
17388            return mServices.bindServiceLocked(caller, token, service,
17389                    resolvedType, connection, flags, callingPackage, userId);
17390        }
17391    }
17392
17393    public boolean unbindService(IServiceConnection connection) {
17394        synchronized (this) {
17395            return mServices.unbindServiceLocked(connection);
17396        }
17397    }
17398
17399    public void publishService(IBinder token, Intent intent, IBinder service) {
17400        // Refuse possible leaked file descriptors
17401        if (intent != null && intent.hasFileDescriptors() == true) {
17402            throw new IllegalArgumentException("File descriptors passed in Intent");
17403        }
17404
17405        synchronized(this) {
17406            if (!(token instanceof ServiceRecord)) {
17407                throw new IllegalArgumentException("Invalid service token");
17408            }
17409            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
17410        }
17411    }
17412
17413    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
17414        // Refuse possible leaked file descriptors
17415        if (intent != null && intent.hasFileDescriptors() == true) {
17416            throw new IllegalArgumentException("File descriptors passed in Intent");
17417        }
17418
17419        synchronized(this) {
17420            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
17421        }
17422    }
17423
17424    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
17425        synchronized(this) {
17426            if (!(token instanceof ServiceRecord)) {
17427                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
17428                throw new IllegalArgumentException("Invalid service token");
17429            }
17430            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
17431        }
17432    }
17433
17434    // =========================================================
17435    // BACKUP AND RESTORE
17436    // =========================================================
17437
17438    // Cause the target app to be launched if necessary and its backup agent
17439    // instantiated.  The backup agent will invoke backupAgentCreated() on the
17440    // activity manager to announce its creation.
17441    public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
17442        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
17443        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
17444
17445        IPackageManager pm = AppGlobals.getPackageManager();
17446        ApplicationInfo app = null;
17447        try {
17448            app = pm.getApplicationInfo(packageName, 0, userId);
17449        } catch (RemoteException e) {
17450            // can't happen; package manager is process-local
17451        }
17452        if (app == null) {
17453            Slog.w(TAG, "Unable to bind backup agent for " + packageName);
17454            return false;
17455        }
17456
17457        synchronized(this) {
17458            // !!! TODO: currently no check here that we're already bound
17459            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
17460            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17461            synchronized (stats) {
17462                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
17463            }
17464
17465            // Backup agent is now in use, its package can't be stopped.
17466            try {
17467                AppGlobals.getPackageManager().setPackageStoppedState(
17468                        app.packageName, false, UserHandle.getUserId(app.uid));
17469            } catch (RemoteException e) {
17470            } catch (IllegalArgumentException e) {
17471                Slog.w(TAG, "Failed trying to unstop package "
17472                        + app.packageName + ": " + e);
17473            }
17474
17475            BackupRecord r = new BackupRecord(ss, app, backupMode);
17476            ComponentName hostingName =
17477                    (backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL)
17478                            ? new ComponentName(app.packageName, app.backupAgentName)
17479                            : new ComponentName("android", "FullBackupAgent");
17480            // startProcessLocked() returns existing proc's record if it's already running
17481            ProcessRecord proc = startProcessLocked(app.processName, app,
17482                    false, 0, "backup", hostingName, false, false, false);
17483            if (proc == null) {
17484                Slog.e(TAG, "Unable to start backup agent process " + r);
17485                return false;
17486            }
17487
17488            // If the app is a regular app (uid >= 10000) and not the system server or phone
17489            // process, etc, then mark it as being in full backup so that certain calls to the
17490            // process can be blocked. This is not reset to false anywhere because we kill the
17491            // process after the full backup is done and the ProcessRecord will vaporize anyway.
17492            if (UserHandle.isApp(app.uid) &&
17493                    backupMode == ApplicationThreadConstants.BACKUP_MODE_FULL) {
17494                proc.inFullBackup = true;
17495            }
17496            r.app = proc;
17497            mBackupTarget = r;
17498            mBackupAppName = app.packageName;
17499
17500            // Try not to kill the process during backup
17501            updateOomAdjLocked(proc);
17502
17503            // If the process is already attached, schedule the creation of the backup agent now.
17504            // If it is not yet live, this will be done when it attaches to the framework.
17505            if (proc.thread != null) {
17506                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
17507                try {
17508                    proc.thread.scheduleCreateBackupAgent(app,
17509                            compatibilityInfoForPackageLocked(app), backupMode);
17510                } catch (RemoteException e) {
17511                    // Will time out on the backup manager side
17512                }
17513            } else {
17514                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
17515            }
17516            // Invariants: at this point, the target app process exists and the application
17517            // is either already running or in the process of coming up.  mBackupTarget and
17518            // mBackupAppName describe the app, so that when it binds back to the AM we
17519            // know that it's scheduled for a backup-agent operation.
17520        }
17521
17522        return true;
17523    }
17524
17525    @Override
17526    public void clearPendingBackup() {
17527        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
17528        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
17529
17530        synchronized (this) {
17531            mBackupTarget = null;
17532            mBackupAppName = null;
17533        }
17534    }
17535
17536    // A backup agent has just come up
17537    public void backupAgentCreated(String agentPackageName, IBinder agent) {
17538        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
17539                + " = " + agent);
17540
17541        synchronized(this) {
17542            if (!agentPackageName.equals(mBackupAppName)) {
17543                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
17544                return;
17545            }
17546        }
17547
17548        long oldIdent = Binder.clearCallingIdentity();
17549        try {
17550            IBackupManager bm = IBackupManager.Stub.asInterface(
17551                    ServiceManager.getService(Context.BACKUP_SERVICE));
17552            bm.agentConnected(agentPackageName, agent);
17553        } catch (RemoteException e) {
17554            // can't happen; the backup manager service is local
17555        } catch (Exception e) {
17556            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
17557            e.printStackTrace();
17558        } finally {
17559            Binder.restoreCallingIdentity(oldIdent);
17560        }
17561    }
17562
17563    // done with this agent
17564    public void unbindBackupAgent(ApplicationInfo appInfo) {
17565        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
17566        if (appInfo == null) {
17567            Slog.w(TAG, "unbind backup agent for null app");
17568            return;
17569        }
17570
17571        synchronized(this) {
17572            try {
17573                if (mBackupAppName == null) {
17574                    Slog.w(TAG, "Unbinding backup agent with no active backup");
17575                    return;
17576                }
17577
17578                if (!mBackupAppName.equals(appInfo.packageName)) {
17579                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
17580                    return;
17581                }
17582
17583                // Not backing this app up any more; reset its OOM adjustment
17584                final ProcessRecord proc = mBackupTarget.app;
17585                updateOomAdjLocked(proc);
17586
17587                // If the app crashed during backup, 'thread' will be null here
17588                if (proc.thread != null) {
17589                    try {
17590                        proc.thread.scheduleDestroyBackupAgent(appInfo,
17591                                compatibilityInfoForPackageLocked(appInfo));
17592                    } catch (Exception e) {
17593                        Slog.e(TAG, "Exception when unbinding backup agent:");
17594                        e.printStackTrace();
17595                    }
17596                }
17597            } finally {
17598                mBackupTarget = null;
17599                mBackupAppName = null;
17600            }
17601        }
17602    }
17603    // =========================================================
17604    // BROADCASTS
17605    // =========================================================
17606
17607    boolean isPendingBroadcastProcessLocked(int pid) {
17608        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
17609                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
17610    }
17611
17612    void skipPendingBroadcastLocked(int pid) {
17613            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
17614            for (BroadcastQueue queue : mBroadcastQueues) {
17615                queue.skipPendingBroadcastLocked(pid);
17616            }
17617    }
17618
17619    // The app just attached; send any pending broadcasts that it should receive
17620    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
17621        boolean didSomething = false;
17622        for (BroadcastQueue queue : mBroadcastQueues) {
17623            didSomething |= queue.sendPendingBroadcastsLocked(app);
17624        }
17625        return didSomething;
17626    }
17627
17628    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
17629            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17630        enforceNotIsolatedCaller("registerReceiver");
17631        ArrayList<Intent> stickyIntents = null;
17632        ProcessRecord callerApp = null;
17633        int callingUid;
17634        int callingPid;
17635        synchronized(this) {
17636            if (caller != null) {
17637                callerApp = getRecordForAppLocked(caller);
17638                if (callerApp == null) {
17639                    throw new SecurityException(
17640                            "Unable to find app for caller " + caller
17641                            + " (pid=" + Binder.getCallingPid()
17642                            + ") when registering receiver " + receiver);
17643                }
17644                if (callerApp.info.uid != Process.SYSTEM_UID &&
17645                        !callerApp.pkgList.containsKey(callerPackage) &&
17646                        !"android".equals(callerPackage)) {
17647                    throw new SecurityException("Given caller package " + callerPackage
17648                            + " is not running in process " + callerApp);
17649                }
17650                callingUid = callerApp.info.uid;
17651                callingPid = callerApp.pid;
17652            } else {
17653                callerPackage = null;
17654                callingUid = Binder.getCallingUid();
17655                callingPid = Binder.getCallingPid();
17656            }
17657
17658            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17659                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17660
17661            Iterator<String> actions = filter.actionsIterator();
17662            if (actions == null) {
17663                ArrayList<String> noAction = new ArrayList<String>(1);
17664                noAction.add(null);
17665                actions = noAction.iterator();
17666            }
17667
17668            // Collect stickies of users
17669            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17670            while (actions.hasNext()) {
17671                String action = actions.next();
17672                for (int id : userIds) {
17673                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17674                    if (stickies != null) {
17675                        ArrayList<Intent> intents = stickies.get(action);
17676                        if (intents != null) {
17677                            if (stickyIntents == null) {
17678                                stickyIntents = new ArrayList<Intent>();
17679                            }
17680                            stickyIntents.addAll(intents);
17681                        }
17682                    }
17683                }
17684            }
17685        }
17686
17687        ArrayList<Intent> allSticky = null;
17688        if (stickyIntents != null) {
17689            final ContentResolver resolver = mContext.getContentResolver();
17690            // Look for any matching sticky broadcasts...
17691            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17692                Intent intent = stickyIntents.get(i);
17693                // If intent has scheme "content", it will need to acccess
17694                // provider that needs to lock mProviderMap in ActivityThread
17695                // and also it may need to wait application response, so we
17696                // cannot lock ActivityManagerService here.
17697                if (filter.match(resolver, intent, true, TAG) >= 0) {
17698                    if (allSticky == null) {
17699                        allSticky = new ArrayList<Intent>();
17700                    }
17701                    allSticky.add(intent);
17702                }
17703            }
17704        }
17705
17706        // The first sticky in the list is returned directly back to the client.
17707        Intent sticky = allSticky != null ? allSticky.get(0) : null;
17708        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17709        if (receiver == null) {
17710            return sticky;
17711        }
17712
17713        synchronized (this) {
17714            if (callerApp != null && (callerApp.thread == null
17715                    || callerApp.thread.asBinder() != caller.asBinder())) {
17716                // Original caller already died
17717                return null;
17718            }
17719            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17720            if (rl == null) {
17721                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17722                        userId, receiver);
17723                if (rl.app != null) {
17724                    rl.app.receivers.add(rl);
17725                } else {
17726                    try {
17727                        receiver.asBinder().linkToDeath(rl, 0);
17728                    } catch (RemoteException e) {
17729                        return sticky;
17730                    }
17731                    rl.linkedToDeath = true;
17732                }
17733                mRegisteredReceivers.put(receiver.asBinder(), rl);
17734            } else if (rl.uid != callingUid) {
17735                throw new IllegalArgumentException(
17736                        "Receiver requested to register for uid " + callingUid
17737                        + " was previously registered for uid " + rl.uid);
17738            } else if (rl.pid != callingPid) {
17739                throw new IllegalArgumentException(
17740                        "Receiver requested to register for pid " + callingPid
17741                        + " was previously registered for pid " + rl.pid);
17742            } else if (rl.userId != userId) {
17743                throw new IllegalArgumentException(
17744                        "Receiver requested to register for user " + userId
17745                        + " was previously registered for user " + rl.userId);
17746            }
17747            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17748                    permission, callingUid, userId);
17749            rl.add(bf);
17750            if (!bf.debugCheck()) {
17751                Slog.w(TAG, "==> For Dynamic broadcast");
17752            }
17753            mReceiverResolver.addFilter(bf);
17754
17755            // Enqueue broadcasts for all existing stickies that match
17756            // this filter.
17757            if (allSticky != null) {
17758                ArrayList receivers = new ArrayList();
17759                receivers.add(bf);
17760
17761                final int stickyCount = allSticky.size();
17762                for (int i = 0; i < stickyCount; i++) {
17763                    Intent intent = allSticky.get(i);
17764                    BroadcastQueue queue = broadcastQueueForIntent(intent);
17765                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17766                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17767                            null, 0, null, null, false, true, true, -1);
17768                    queue.enqueueParallelBroadcastLocked(r);
17769                    queue.scheduleBroadcastsLocked();
17770                }
17771            }
17772
17773            return sticky;
17774        }
17775    }
17776
17777    public void unregisterReceiver(IIntentReceiver receiver) {
17778        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17779
17780        final long origId = Binder.clearCallingIdentity();
17781        try {
17782            boolean doTrim = false;
17783
17784            synchronized(this) {
17785                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17786                if (rl != null) {
17787                    final BroadcastRecord r = rl.curBroadcast;
17788                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17789                        final boolean doNext = r.queue.finishReceiverLocked(
17790                                r, r.resultCode, r.resultData, r.resultExtras,
17791                                r.resultAbort, false);
17792                        if (doNext) {
17793                            doTrim = true;
17794                            r.queue.processNextBroadcast(false);
17795                        }
17796                    }
17797
17798                    if (rl.app != null) {
17799                        rl.app.receivers.remove(rl);
17800                    }
17801                    removeReceiverLocked(rl);
17802                    if (rl.linkedToDeath) {
17803                        rl.linkedToDeath = false;
17804                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
17805                    }
17806                }
17807            }
17808
17809            // If we actually concluded any broadcasts, we might now be able
17810            // to trim the recipients' apps from our working set
17811            if (doTrim) {
17812                trimApplications();
17813                return;
17814            }
17815
17816        } finally {
17817            Binder.restoreCallingIdentity(origId);
17818        }
17819    }
17820
17821    void removeReceiverLocked(ReceiverList rl) {
17822        mRegisteredReceivers.remove(rl.receiver.asBinder());
17823        for (int i = rl.size() - 1; i >= 0; i--) {
17824            mReceiverResolver.removeFilter(rl.get(i));
17825        }
17826    }
17827
17828    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17829        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17830            ProcessRecord r = mLruProcesses.get(i);
17831            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17832                try {
17833                    r.thread.dispatchPackageBroadcast(cmd, packages);
17834                } catch (RemoteException ex) {
17835                }
17836            }
17837        }
17838    }
17839
17840    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17841            int callingUid, int[] users) {
17842        // TODO: come back and remove this assumption to triage all broadcasts
17843        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17844
17845        List<ResolveInfo> receivers = null;
17846        try {
17847            HashSet<ComponentName> singleUserReceivers = null;
17848            boolean scannedFirstReceivers = false;
17849            for (int user : users) {
17850                // Skip users that have Shell restrictions, with exception of always permitted
17851                // Shell broadcasts
17852                if (callingUid == Process.SHELL_UID
17853                        && mUserController.hasUserRestriction(
17854                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17855                        && !isPermittedShellBroadcast(intent)) {
17856                    continue;
17857                }
17858                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17859                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17860                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17861                    // If this is not the system user, we need to check for
17862                    // any receivers that should be filtered out.
17863                    for (int i=0; i<newReceivers.size(); i++) {
17864                        ResolveInfo ri = newReceivers.get(i);
17865                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17866                            newReceivers.remove(i);
17867                            i--;
17868                        }
17869                    }
17870                }
17871                if (newReceivers != null && newReceivers.size() == 0) {
17872                    newReceivers = null;
17873                }
17874                if (receivers == null) {
17875                    receivers = newReceivers;
17876                } else if (newReceivers != null) {
17877                    // We need to concatenate the additional receivers
17878                    // found with what we have do far.  This would be easy,
17879                    // but we also need to de-dup any receivers that are
17880                    // singleUser.
17881                    if (!scannedFirstReceivers) {
17882                        // Collect any single user receivers we had already retrieved.
17883                        scannedFirstReceivers = true;
17884                        for (int i=0; i<receivers.size(); i++) {
17885                            ResolveInfo ri = receivers.get(i);
17886                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17887                                ComponentName cn = new ComponentName(
17888                                        ri.activityInfo.packageName, ri.activityInfo.name);
17889                                if (singleUserReceivers == null) {
17890                                    singleUserReceivers = new HashSet<ComponentName>();
17891                                }
17892                                singleUserReceivers.add(cn);
17893                            }
17894                        }
17895                    }
17896                    // Add the new results to the existing results, tracking
17897                    // and de-dupping single user receivers.
17898                    for (int i=0; i<newReceivers.size(); i++) {
17899                        ResolveInfo ri = newReceivers.get(i);
17900                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17901                            ComponentName cn = new ComponentName(
17902                                    ri.activityInfo.packageName, ri.activityInfo.name);
17903                            if (singleUserReceivers == null) {
17904                                singleUserReceivers = new HashSet<ComponentName>();
17905                            }
17906                            if (!singleUserReceivers.contains(cn)) {
17907                                singleUserReceivers.add(cn);
17908                                receivers.add(ri);
17909                            }
17910                        } else {
17911                            receivers.add(ri);
17912                        }
17913                    }
17914                }
17915            }
17916        } catch (RemoteException ex) {
17917            // pm is in same process, this will never happen.
17918        }
17919        return receivers;
17920    }
17921
17922    private boolean isPermittedShellBroadcast(Intent intent) {
17923        // remote bugreport should always be allowed to be taken
17924        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17925    }
17926
17927    private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
17928            String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
17929        if ((intent.getFlags() & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
17930            // Don't yell about broadcasts sent via shell
17931            return;
17932        }
17933
17934        final String action = intent.getAction();
17935        if (isProtectedBroadcast
17936                || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17937                || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17938                || Intent.ACTION_MEDIA_BUTTON.equals(action)
17939                || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17940                || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17941                || Intent.ACTION_MASTER_CLEAR.equals(action)
17942                || Intent.ACTION_FACTORY_RESET.equals(action)
17943                || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17944                || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17945                || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
17946                || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
17947                || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
17948            // Broadcast is either protected, or it's a public action that
17949            // we've relaxed, so it's fine for system internals to send.
17950            return;
17951        }
17952
17953        // This broadcast may be a problem...  but there are often system components that
17954        // want to send an internal broadcast to themselves, which is annoying to have to
17955        // explicitly list each action as a protected broadcast, so we will check for that
17956        // one safe case and allow it: an explicit broadcast, only being received by something
17957        // that has protected itself.
17958        if (receivers != null && receivers.size() > 0
17959                && (intent.getPackage() != null || intent.getComponent() != null)) {
17960            boolean allProtected = true;
17961            for (int i = receivers.size()-1; i >= 0; i--) {
17962                Object target = receivers.get(i);
17963                if (target instanceof ResolveInfo) {
17964                    ResolveInfo ri = (ResolveInfo)target;
17965                    if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
17966                        allProtected = false;
17967                        break;
17968                    }
17969                } else {
17970                    BroadcastFilter bf = (BroadcastFilter)target;
17971                    if (bf.requiredPermission == null) {
17972                        allProtected = false;
17973                        break;
17974                    }
17975                }
17976            }
17977            if (allProtected) {
17978                // All safe!
17979                return;
17980            }
17981        }
17982
17983        // The vast majority of broadcasts sent from system internals
17984        // should be protected to avoid security holes, so yell loudly
17985        // to ensure we examine these cases.
17986        if (callerApp != null) {
17987            Log.wtf(TAG, "Sending non-protected broadcast " + action
17988                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
17989                    new Throwable());
17990        } else {
17991            Log.wtf(TAG, "Sending non-protected broadcast " + action
17992                            + " from system uid " + UserHandle.formatUid(callingUid)
17993                            + " pkg " + callerPackage,
17994                    new Throwable());
17995        }
17996    }
17997
17998    final int broadcastIntentLocked(ProcessRecord callerApp,
17999            String callerPackage, Intent intent, String resolvedType,
18000            IIntentReceiver resultTo, int resultCode, String resultData,
18001            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
18002            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
18003        intent = new Intent(intent);
18004
18005        // By default broadcasts do not go to stopped apps.
18006        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
18007
18008        // If we have not finished booting, don't allow this to launch new processes.
18009        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
18010            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18011        }
18012
18013        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
18014                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
18015                + " ordered=" + ordered + " userid=" + userId);
18016        if ((resultTo != null) && !ordered) {
18017            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
18018        }
18019
18020        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
18021                ALLOW_NON_FULL, "broadcast", callerPackage);
18022
18023        // Make sure that the user who is receiving this broadcast is running.
18024        // If not, we will just skip it. Make an exception for shutdown broadcasts
18025        // and upgrade steps.
18026
18027        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
18028            if ((callingUid != Process.SYSTEM_UID
18029                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
18030                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
18031                Slog.w(TAG, "Skipping broadcast of " + intent
18032                        + ": user " + userId + " is stopped");
18033                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
18034            }
18035        }
18036
18037        BroadcastOptions brOptions = null;
18038        if (bOptions != null) {
18039            brOptions = new BroadcastOptions(bOptions);
18040            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
18041                // See if the caller is allowed to do this.  Note we are checking against
18042                // the actual real caller (not whoever provided the operation as say a
18043                // PendingIntent), because that who is actually supplied the arguments.
18044                if (checkComponentPermission(
18045                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
18046                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
18047                        != PackageManager.PERMISSION_GRANTED) {
18048                    String msg = "Permission Denial: " + intent.getAction()
18049                            + " broadcast from " + callerPackage + " (pid=" + callingPid
18050                            + ", uid=" + callingUid + ")"
18051                            + " requires "
18052                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
18053                    Slog.w(TAG, msg);
18054                    throw new SecurityException(msg);
18055                }
18056            }
18057        }
18058
18059        // Verify that protected broadcasts are only being sent by system code,
18060        // and that system code is only sending protected broadcasts.
18061        final String action = intent.getAction();
18062        final boolean isProtectedBroadcast;
18063        try {
18064            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
18065        } catch (RemoteException e) {
18066            Slog.w(TAG, "Remote exception", e);
18067            return ActivityManager.BROADCAST_SUCCESS;
18068        }
18069
18070        final boolean isCallerSystem;
18071        switch (UserHandle.getAppId(callingUid)) {
18072            case Process.ROOT_UID:
18073            case Process.SYSTEM_UID:
18074            case Process.PHONE_UID:
18075            case Process.BLUETOOTH_UID:
18076            case Process.NFC_UID:
18077                isCallerSystem = true;
18078                break;
18079            default:
18080                isCallerSystem = (callerApp != null) && callerApp.persistent;
18081                break;
18082        }
18083
18084        // First line security check before anything else: stop non-system apps from
18085        // sending protected broadcasts.
18086        if (!isCallerSystem) {
18087            if (isProtectedBroadcast) {
18088                String msg = "Permission Denial: not allowed to send broadcast "
18089                        + action + " from pid="
18090                        + callingPid + ", uid=" + callingUid;
18091                Slog.w(TAG, msg);
18092                throw new SecurityException(msg);
18093
18094            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
18095                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
18096                // Special case for compatibility: we don't want apps to send this,
18097                // but historically it has not been protected and apps may be using it
18098                // to poke their own app widget.  So, instead of making it protected,
18099                // just limit it to the caller.
18100                if (callerPackage == null) {
18101                    String msg = "Permission Denial: not allowed to send broadcast "
18102                            + action + " from unknown caller.";
18103                    Slog.w(TAG, msg);
18104                    throw new SecurityException(msg);
18105                } else if (intent.getComponent() != null) {
18106                    // They are good enough to send to an explicit component...  verify
18107                    // it is being sent to the calling app.
18108                    if (!intent.getComponent().getPackageName().equals(
18109                            callerPackage)) {
18110                        String msg = "Permission Denial: not allowed to send broadcast "
18111                                + action + " to "
18112                                + intent.getComponent().getPackageName() + " from "
18113                                + callerPackage;
18114                        Slog.w(TAG, msg);
18115                        throw new SecurityException(msg);
18116                    }
18117                } else {
18118                    // Limit broadcast to their own package.
18119                    intent.setPackage(callerPackage);
18120                }
18121            }
18122        }
18123
18124        if (action != null) {
18125            switch (action) {
18126                case Intent.ACTION_UID_REMOVED:
18127                case Intent.ACTION_PACKAGE_REMOVED:
18128                case Intent.ACTION_PACKAGE_CHANGED:
18129                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
18130                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
18131                case Intent.ACTION_PACKAGES_SUSPENDED:
18132                case Intent.ACTION_PACKAGES_UNSUSPENDED:
18133                    // Handle special intents: if this broadcast is from the package
18134                    // manager about a package being removed, we need to remove all of
18135                    // its activities from the history stack.
18136                    if (checkComponentPermission(
18137                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
18138                            callingPid, callingUid, -1, true)
18139                            != PackageManager.PERMISSION_GRANTED) {
18140                        String msg = "Permission Denial: " + intent.getAction()
18141                                + " broadcast from " + callerPackage + " (pid=" + callingPid
18142                                + ", uid=" + callingUid + ")"
18143                                + " requires "
18144                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
18145                        Slog.w(TAG, msg);
18146                        throw new SecurityException(msg);
18147                    }
18148                    switch (action) {
18149                        case Intent.ACTION_UID_REMOVED:
18150                            final Bundle intentExtras = intent.getExtras();
18151                            final int uid = intentExtras != null
18152                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
18153                            if (uid >= 0) {
18154                                mBatteryStatsService.removeUid(uid);
18155                                mAppOpsService.uidRemoved(uid);
18156                            }
18157                            break;
18158                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
18159                            // If resources are unavailable just force stop all those packages
18160                            // and flush the attribute cache as well.
18161                            String list[] =
18162                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18163                            if (list != null && list.length > 0) {
18164                                for (int i = 0; i < list.length; i++) {
18165                                    forceStopPackageLocked(list[i], -1, false, true, true,
18166                                            false, false, userId, "storage unmount");
18167                                }
18168                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
18169                                sendPackageBroadcastLocked(
18170                                        ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE,
18171                                        list, userId);
18172                            }
18173                            break;
18174                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
18175                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
18176                            break;
18177                        case Intent.ACTION_PACKAGE_REMOVED:
18178                        case Intent.ACTION_PACKAGE_CHANGED:
18179                            Uri data = intent.getData();
18180                            String ssp;
18181                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
18182                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
18183                                final boolean replacing =
18184                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
18185                                final boolean killProcess =
18186                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
18187                                final boolean fullUninstall = removed && !replacing;
18188                                if (removed) {
18189                                    if (killProcess) {
18190                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
18191                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
18192                                                false, true, true, false, fullUninstall, userId,
18193                                                removed ? "pkg removed" : "pkg changed");
18194                                    }
18195                                    final int cmd = killProcess
18196                                            ? ApplicationThreadConstants.PACKAGE_REMOVED
18197                                            : ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL;
18198                                    sendPackageBroadcastLocked(cmd,
18199                                            new String[] {ssp}, userId);
18200                                    if (fullUninstall) {
18201                                        mAppOpsService.packageRemoved(
18202                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
18203
18204                                        // Remove all permissions granted from/to this package
18205                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
18206
18207                                        removeTasksByPackageNameLocked(ssp, userId);
18208
18209                                        // Hide the "unsupported display" dialog if necessary.
18210                                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
18211                                                mUnsupportedDisplaySizeDialog.getPackageName())) {
18212                                            mUnsupportedDisplaySizeDialog.dismiss();
18213                                            mUnsupportedDisplaySizeDialog = null;
18214                                        }
18215                                        mCompatModePackages.handlePackageUninstalledLocked(ssp);
18216                                        mBatteryStatsService.notePackageUninstalled(ssp);
18217                                    }
18218                                } else {
18219                                    if (killProcess) {
18220                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
18221                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
18222                                                userId, ProcessList.INVALID_ADJ,
18223                                                false, true, true, false, "change " + ssp);
18224                                    }
18225                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
18226                                            intent.getStringArrayExtra(
18227                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
18228                                }
18229                            }
18230                            break;
18231                        case Intent.ACTION_PACKAGES_SUSPENDED:
18232                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
18233                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
18234                                    intent.getAction());
18235                            final String[] packageNames = intent.getStringArrayExtra(
18236                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
18237                            final int userHandle = intent.getIntExtra(
18238                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
18239
18240                            synchronized(ActivityManagerService.this) {
18241                                mRecentTasks.onPackagesSuspendedChanged(
18242                                        packageNames, suspended, userHandle);
18243                            }
18244                            break;
18245                    }
18246                    break;
18247                case Intent.ACTION_PACKAGE_REPLACED:
18248                {
18249                    final Uri data = intent.getData();
18250                    final String ssp;
18251                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18252                        final ApplicationInfo aInfo =
18253                                getPackageManagerInternalLocked().getApplicationInfo(
18254                                        ssp,
18255                                        userId);
18256                        if (aInfo == null) {
18257                            Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
18258                                    + " ssp=" + ssp + " data=" + data);
18259                            return ActivityManager.BROADCAST_SUCCESS;
18260                        }
18261                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
18262                        sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED,
18263                                new String[] {ssp}, userId);
18264                    }
18265                    break;
18266                }
18267                case Intent.ACTION_PACKAGE_ADDED:
18268                {
18269                    // Special case for adding a package: by default turn on compatibility mode.
18270                    Uri data = intent.getData();
18271                    String ssp;
18272                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18273                        final boolean replacing =
18274                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
18275                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
18276
18277                        try {
18278                            ApplicationInfo ai = AppGlobals.getPackageManager().
18279                                    getApplicationInfo(ssp, 0, 0);
18280                            mBatteryStatsService.notePackageInstalled(ssp,
18281                                    ai != null ? ai.versionCode : 0);
18282                        } catch (RemoteException e) {
18283                        }
18284                    }
18285                    break;
18286                }
18287                case Intent.ACTION_PACKAGE_DATA_CLEARED:
18288                {
18289                    Uri data = intent.getData();
18290                    String ssp;
18291                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18292                        // Hide the "unsupported display" dialog if necessary.
18293                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
18294                                mUnsupportedDisplaySizeDialog.getPackageName())) {
18295                            mUnsupportedDisplaySizeDialog.dismiss();
18296                            mUnsupportedDisplaySizeDialog = null;
18297                        }
18298                        mCompatModePackages.handlePackageDataClearedLocked(ssp);
18299                    }
18300                    break;
18301                }
18302                case Intent.ACTION_TIMEZONE_CHANGED:
18303                    // If this is the time zone changed action, queue up a message that will reset
18304                    // the timezone of all currently running processes. This message will get
18305                    // queued up before the broadcast happens.
18306                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
18307                    break;
18308                case Intent.ACTION_TIME_CHANGED:
18309                    // EXTRA_TIME_PREF_24_HOUR_FORMAT is optional so we must distinguish between
18310                    // the tri-state value it may contain and "unknown".
18311                    // For convenience we re-use the Intent extra values.
18312                    final int NO_EXTRA_VALUE_FOUND = -1;
18313                    final int timeFormatPreferenceMsgValue = intent.getIntExtra(
18314                            Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT,
18315                            NO_EXTRA_VALUE_FOUND /* defaultValue */);
18316                    // Only send a message if the time preference is available.
18317                    if (timeFormatPreferenceMsgValue != NO_EXTRA_VALUE_FOUND) {
18318                        Message updateTimePreferenceMsg =
18319                                mHandler.obtainMessage(UPDATE_TIME_PREFERENCE_MSG,
18320                                        timeFormatPreferenceMsgValue, 0);
18321                        mHandler.sendMessage(updateTimePreferenceMsg);
18322                    }
18323                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18324                    synchronized (stats) {
18325                        stats.noteCurrentTimeChangedLocked();
18326                    }
18327                    break;
18328                case Intent.ACTION_CLEAR_DNS_CACHE:
18329                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
18330                    break;
18331                case Proxy.PROXY_CHANGE_ACTION:
18332                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
18333                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
18334                    break;
18335                case android.hardware.Camera.ACTION_NEW_PICTURE:
18336                case android.hardware.Camera.ACTION_NEW_VIDEO:
18337                    // These broadcasts are no longer allowed by the system, since they can
18338                    // cause significant thrashing at a crictical point (using the camera).
18339                    // Apps should use JobScehduler to monitor for media provider changes.
18340                    Slog.w(TAG, action + " no longer allowed; dropping from "
18341                            + UserHandle.formatUid(callingUid));
18342                    if (resultTo != null) {
18343                        final BroadcastQueue queue = broadcastQueueForIntent(intent);
18344                        try {
18345                            queue.performReceiveLocked(callerApp, resultTo, intent,
18346                                    Activity.RESULT_CANCELED, null, null,
18347                                    false, false, userId);
18348                        } catch (RemoteException e) {
18349                            Slog.w(TAG, "Failure ["
18350                                    + queue.mQueueName + "] sending broadcast result of "
18351                                    + intent, e);
18352
18353                        }
18354                    }
18355                    // Lie; we don't want to crash the app.
18356                    return ActivityManager.BROADCAST_SUCCESS;
18357                case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED:
18358                    mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG);
18359                    break;
18360            }
18361        }
18362
18363        // Add to the sticky list if requested.
18364        if (sticky) {
18365            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
18366                    callingPid, callingUid)
18367                    != PackageManager.PERMISSION_GRANTED) {
18368                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
18369                        + callingPid + ", uid=" + callingUid
18370                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18371                Slog.w(TAG, msg);
18372                throw new SecurityException(msg);
18373            }
18374            if (requiredPermissions != null && requiredPermissions.length > 0) {
18375                Slog.w(TAG, "Can't broadcast sticky intent " + intent
18376                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
18377                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
18378            }
18379            if (intent.getComponent() != null) {
18380                throw new SecurityException(
18381                        "Sticky broadcasts can't target a specific component");
18382            }
18383            // We use userId directly here, since the "all" target is maintained
18384            // as a separate set of sticky broadcasts.
18385            if (userId != UserHandle.USER_ALL) {
18386                // But first, if this is not a broadcast to all users, then
18387                // make sure it doesn't conflict with an existing broadcast to
18388                // all users.
18389                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
18390                        UserHandle.USER_ALL);
18391                if (stickies != null) {
18392                    ArrayList<Intent> list = stickies.get(intent.getAction());
18393                    if (list != null) {
18394                        int N = list.size();
18395                        int i;
18396                        for (i=0; i<N; i++) {
18397                            if (intent.filterEquals(list.get(i))) {
18398                                throw new IllegalArgumentException(
18399                                        "Sticky broadcast " + intent + " for user "
18400                                        + userId + " conflicts with existing global broadcast");
18401                            }
18402                        }
18403                    }
18404                }
18405            }
18406            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18407            if (stickies == null) {
18408                stickies = new ArrayMap<>();
18409                mStickyBroadcasts.put(userId, stickies);
18410            }
18411            ArrayList<Intent> list = stickies.get(intent.getAction());
18412            if (list == null) {
18413                list = new ArrayList<>();
18414                stickies.put(intent.getAction(), list);
18415            }
18416            final int stickiesCount = list.size();
18417            int i;
18418            for (i = 0; i < stickiesCount; i++) {
18419                if (intent.filterEquals(list.get(i))) {
18420                    // This sticky already exists, replace it.
18421                    list.set(i, new Intent(intent));
18422                    break;
18423                }
18424            }
18425            if (i >= stickiesCount) {
18426                list.add(new Intent(intent));
18427            }
18428        }
18429
18430        int[] users;
18431        if (userId == UserHandle.USER_ALL) {
18432            // Caller wants broadcast to go to all started users.
18433            users = mUserController.getStartedUserArrayLocked();
18434        } else {
18435            // Caller wants broadcast to go to one specific user.
18436            users = new int[] {userId};
18437        }
18438
18439        // Figure out who all will receive this broadcast.
18440        List receivers = null;
18441        List<BroadcastFilter> registeredReceivers = null;
18442        // Need to resolve the intent to interested receivers...
18443        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
18444                 == 0) {
18445            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
18446        }
18447        if (intent.getComponent() == null) {
18448            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
18449                // Query one target user at a time, excluding shell-restricted users
18450                for (int i = 0; i < users.length; i++) {
18451                    if (mUserController.hasUserRestriction(
18452                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
18453                        continue;
18454                    }
18455                    List<BroadcastFilter> registeredReceiversForUser =
18456                            mReceiverResolver.queryIntent(intent,
18457                                    resolvedType, false, false /*visibleToEphemeral*/,
18458                                    false /*isEphemeral*/, users[i]);
18459                    if (registeredReceivers == null) {
18460                        registeredReceivers = registeredReceiversForUser;
18461                    } else if (registeredReceiversForUser != null) {
18462                        registeredReceivers.addAll(registeredReceiversForUser);
18463                    }
18464                }
18465            } else {
18466                registeredReceivers = mReceiverResolver.queryIntent(intent,
18467                        resolvedType, false, false /*visibleToEphemeral*/,
18468                        false /*isEphemeral*/, userId);
18469            }
18470        }
18471
18472        final boolean replacePending =
18473                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
18474
18475        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
18476                + " replacePending=" + replacePending);
18477
18478        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
18479        if (!ordered && NR > 0) {
18480            // If we are not serializing this broadcast, then send the
18481            // registered receivers separately so they don't wait for the
18482            // components to be launched.
18483            if (isCallerSystem) {
18484                checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
18485                        isProtectedBroadcast, registeredReceivers);
18486            }
18487            final BroadcastQueue queue = broadcastQueueForIntent(intent);
18488            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18489                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
18490                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
18491                    resultExtras, ordered, sticky, false, userId);
18492            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
18493            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
18494            if (!replaced) {
18495                queue.enqueueParallelBroadcastLocked(r);
18496                queue.scheduleBroadcastsLocked();
18497            }
18498            registeredReceivers = null;
18499            NR = 0;
18500        }
18501
18502        // Merge into one list.
18503        int ir = 0;
18504        if (receivers != null) {
18505            // A special case for PACKAGE_ADDED: do not allow the package
18506            // being added to see this broadcast.  This prevents them from
18507            // using this as a back door to get run as soon as they are
18508            // installed.  Maybe in the future we want to have a special install
18509            // broadcast or such for apps, but we'd like to deliberately make
18510            // this decision.
18511            String skipPackages[] = null;
18512            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
18513                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
18514                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
18515                Uri data = intent.getData();
18516                if (data != null) {
18517                    String pkgName = data.getSchemeSpecificPart();
18518                    if (pkgName != null) {
18519                        skipPackages = new String[] { pkgName };
18520                    }
18521                }
18522            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
18523                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18524            }
18525            if (skipPackages != null && (skipPackages.length > 0)) {
18526                for (String skipPackage : skipPackages) {
18527                    if (skipPackage != null) {
18528                        int NT = receivers.size();
18529                        for (int it=0; it<NT; it++) {
18530                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
18531                            if (curt.activityInfo.packageName.equals(skipPackage)) {
18532                                receivers.remove(it);
18533                                it--;
18534                                NT--;
18535                            }
18536                        }
18537                    }
18538                }
18539            }
18540
18541            int NT = receivers != null ? receivers.size() : 0;
18542            int it = 0;
18543            ResolveInfo curt = null;
18544            BroadcastFilter curr = null;
18545            while (it < NT && ir < NR) {
18546                if (curt == null) {
18547                    curt = (ResolveInfo)receivers.get(it);
18548                }
18549                if (curr == null) {
18550                    curr = registeredReceivers.get(ir);
18551                }
18552                if (curr.getPriority() >= curt.priority) {
18553                    // Insert this broadcast record into the final list.
18554                    receivers.add(it, curr);
18555                    ir++;
18556                    curr = null;
18557                    it++;
18558                    NT++;
18559                } else {
18560                    // Skip to the next ResolveInfo in the final list.
18561                    it++;
18562                    curt = null;
18563                }
18564            }
18565        }
18566        while (ir < NR) {
18567            if (receivers == null) {
18568                receivers = new ArrayList();
18569            }
18570            receivers.add(registeredReceivers.get(ir));
18571            ir++;
18572        }
18573
18574        if (isCallerSystem) {
18575            checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
18576                    isProtectedBroadcast, receivers);
18577        }
18578
18579        if ((receivers != null && receivers.size() > 0)
18580                || resultTo != null) {
18581            BroadcastQueue queue = broadcastQueueForIntent(intent);
18582            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18583                    callerPackage, callingPid, callingUid, resolvedType,
18584                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
18585                    resultData, resultExtras, ordered, sticky, false, userId);
18586
18587            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
18588                    + ": prev had " + queue.mOrderedBroadcasts.size());
18589            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
18590                    "Enqueueing broadcast " + r.intent.getAction());
18591
18592            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
18593            if (!replaced) {
18594                queue.enqueueOrderedBroadcastLocked(r);
18595                queue.scheduleBroadcastsLocked();
18596            }
18597        } else {
18598            // There was nobody interested in the broadcast, but we still want to record
18599            // that it happened.
18600            if (intent.getComponent() == null && intent.getPackage() == null
18601                    && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18602                // This was an implicit broadcast... let's record it for posterity.
18603                addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
18604            }
18605        }
18606
18607        return ActivityManager.BROADCAST_SUCCESS;
18608    }
18609
18610    final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
18611            int skipCount, long dispatchTime) {
18612        final long now = SystemClock.elapsedRealtime();
18613        if (mCurBroadcastStats == null ||
18614                (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
18615            mLastBroadcastStats = mCurBroadcastStats;
18616            if (mLastBroadcastStats != null) {
18617                mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
18618                mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
18619            }
18620            mCurBroadcastStats = new BroadcastStats();
18621        }
18622        mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
18623    }
18624
18625    final Intent verifyBroadcastLocked(Intent intent) {
18626        // Refuse possible leaked file descriptors
18627        if (intent != null && intent.hasFileDescriptors() == true) {
18628            throw new IllegalArgumentException("File descriptors passed in Intent");
18629        }
18630
18631        int flags = intent.getFlags();
18632
18633        if (!mProcessesReady) {
18634            // if the caller really truly claims to know what they're doing, go
18635            // ahead and allow the broadcast without launching any receivers
18636            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
18637                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
18638            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18639                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
18640                        + " before boot completion");
18641                throw new IllegalStateException("Cannot broadcast before boot completed");
18642            }
18643        }
18644
18645        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
18646            throw new IllegalArgumentException(
18647                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
18648        }
18649
18650        if ((flags & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
18651            switch (Binder.getCallingUid()) {
18652                case Process.ROOT_UID:
18653                case Process.SHELL_UID:
18654                    break;
18655                default:
18656                    Slog.w(TAG, "Removing FLAG_RECEIVER_FROM_SHELL because caller is UID "
18657                            + Binder.getCallingUid());
18658                    intent.removeFlags(Intent.FLAG_RECEIVER_FROM_SHELL);
18659                    break;
18660            }
18661        }
18662
18663        return intent;
18664    }
18665
18666    public final int broadcastIntent(IApplicationThread caller,
18667            Intent intent, String resolvedType, IIntentReceiver resultTo,
18668            int resultCode, String resultData, Bundle resultExtras,
18669            String[] requiredPermissions, int appOp, Bundle bOptions,
18670            boolean serialized, boolean sticky, int userId) {
18671        enforceNotIsolatedCaller("broadcastIntent");
18672        synchronized(this) {
18673            intent = verifyBroadcastLocked(intent);
18674
18675            final ProcessRecord callerApp = getRecordForAppLocked(caller);
18676            final int callingPid = Binder.getCallingPid();
18677            final int callingUid = Binder.getCallingUid();
18678            final long origId = Binder.clearCallingIdentity();
18679            int res = broadcastIntentLocked(callerApp,
18680                    callerApp != null ? callerApp.info.packageName : null,
18681                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
18682                    requiredPermissions, appOp, bOptions, serialized, sticky,
18683                    callingPid, callingUid, userId);
18684            Binder.restoreCallingIdentity(origId);
18685            return res;
18686        }
18687    }
18688
18689
18690    int broadcastIntentInPackage(String packageName, int uid,
18691            Intent intent, String resolvedType, IIntentReceiver resultTo,
18692            int resultCode, String resultData, Bundle resultExtras,
18693            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
18694            int userId) {
18695        synchronized(this) {
18696            intent = verifyBroadcastLocked(intent);
18697
18698            final long origId = Binder.clearCallingIdentity();
18699            String[] requiredPermissions = requiredPermission == null ? null
18700                    : new String[] {requiredPermission};
18701            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
18702                    resultTo, resultCode, resultData, resultExtras,
18703                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
18704                    sticky, -1, uid, userId);
18705            Binder.restoreCallingIdentity(origId);
18706            return res;
18707        }
18708    }
18709
18710    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
18711        // Refuse possible leaked file descriptors
18712        if (intent != null && intent.hasFileDescriptors() == true) {
18713            throw new IllegalArgumentException("File descriptors passed in Intent");
18714        }
18715
18716        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18717                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
18718
18719        synchronized(this) {
18720            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
18721                    != PackageManager.PERMISSION_GRANTED) {
18722                String msg = "Permission Denial: unbroadcastIntent() from pid="
18723                        + Binder.getCallingPid()
18724                        + ", uid=" + Binder.getCallingUid()
18725                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18726                Slog.w(TAG, msg);
18727                throw new SecurityException(msg);
18728            }
18729            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18730            if (stickies != null) {
18731                ArrayList<Intent> list = stickies.get(intent.getAction());
18732                if (list != null) {
18733                    int N = list.size();
18734                    int i;
18735                    for (i=0; i<N; i++) {
18736                        if (intent.filterEquals(list.get(i))) {
18737                            list.remove(i);
18738                            break;
18739                        }
18740                    }
18741                    if (list.size() <= 0) {
18742                        stickies.remove(intent.getAction());
18743                    }
18744                }
18745                if (stickies.size() <= 0) {
18746                    mStickyBroadcasts.remove(userId);
18747                }
18748            }
18749        }
18750    }
18751
18752    void backgroundServicesFinishedLocked(int userId) {
18753        for (BroadcastQueue queue : mBroadcastQueues) {
18754            queue.backgroundServicesFinishedLocked(userId);
18755        }
18756    }
18757
18758    public void finishReceiver(IBinder who, int resultCode, String resultData,
18759            Bundle resultExtras, boolean resultAbort, int flags) {
18760        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
18761
18762        // Refuse possible leaked file descriptors
18763        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
18764            throw new IllegalArgumentException("File descriptors passed in Bundle");
18765        }
18766
18767        final long origId = Binder.clearCallingIdentity();
18768        try {
18769            boolean doNext = false;
18770            BroadcastRecord r;
18771
18772            synchronized(this) {
18773                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
18774                        ? mFgBroadcastQueue : mBgBroadcastQueue;
18775                r = queue.getMatchingOrderedReceiver(who);
18776                if (r != null) {
18777                    doNext = r.queue.finishReceiverLocked(r, resultCode,
18778                        resultData, resultExtras, resultAbort, true);
18779                }
18780            }
18781
18782            if (doNext) {
18783                if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
18784                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
18785                      String.format("ProcessBroadcast from %s (%s) %s", r.callerPackage,
18786                        r.callerApp == null ? "caller unknown" : r.callerApp.toShortString(),
18787                        r.intent == null ? "" : r.intent.toString()));
18788                }
18789                r.queue.processNextBroadcast(false);
18790                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
18791            }
18792            trimApplications();
18793        } finally {
18794            Binder.restoreCallingIdentity(origId);
18795        }
18796    }
18797
18798    // =========================================================
18799    // INSTRUMENTATION
18800    // =========================================================
18801
18802    public boolean startInstrumentation(ComponentName className,
18803            String profileFile, int flags, Bundle arguments,
18804            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
18805            int userId, String abiOverride) {
18806        enforceNotIsolatedCaller("startInstrumentation");
18807        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18808                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
18809        // Refuse possible leaked file descriptors
18810        if (arguments != null && arguments.hasFileDescriptors()) {
18811            throw new IllegalArgumentException("File descriptors passed in Bundle");
18812        }
18813
18814        synchronized(this) {
18815            InstrumentationInfo ii = null;
18816            ApplicationInfo ai = null;
18817            try {
18818                ii = mContext.getPackageManager().getInstrumentationInfo(
18819                    className, STOCK_PM_FLAGS);
18820                ai = AppGlobals.getPackageManager().getApplicationInfo(
18821                        ii.targetPackage, STOCK_PM_FLAGS, userId);
18822            } catch (PackageManager.NameNotFoundException e) {
18823            } catch (RemoteException e) {
18824            }
18825            if (ii == null) {
18826                reportStartInstrumentationFailureLocked(watcher, className,
18827                        "Unable to find instrumentation info for: " + className);
18828                return false;
18829            }
18830            if (ai == null) {
18831                reportStartInstrumentationFailureLocked(watcher, className,
18832                        "Unable to find instrumentation target package: " + ii.targetPackage);
18833                return false;
18834            }
18835            if (!ai.hasCode()) {
18836                reportStartInstrumentationFailureLocked(watcher, className,
18837                        "Instrumentation target has no code: " + ii.targetPackage);
18838                return false;
18839            }
18840
18841            int match = mContext.getPackageManager().checkSignatures(
18842                    ii.targetPackage, ii.packageName);
18843            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18844                String msg = "Permission Denial: starting instrumentation "
18845                        + className + " from pid="
18846                        + Binder.getCallingPid()
18847                        + ", uid=" + Binder.getCallingPid()
18848                        + " not allowed because package " + ii.packageName
18849                        + " does not have a signature matching the target "
18850                        + ii.targetPackage;
18851                reportStartInstrumentationFailureLocked(watcher, className, msg);
18852                throw new SecurityException(msg);
18853            }
18854
18855            final long origId = Binder.clearCallingIdentity();
18856            // Instrumentation can kill and relaunch even persistent processes
18857            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18858                    "start instr");
18859            ProcessRecord app = addAppLocked(ai, false, abiOverride);
18860            app.instrumentationClass = className;
18861            app.instrumentationInfo = ai;
18862            app.instrumentationProfileFile = profileFile;
18863            app.instrumentationArguments = arguments;
18864            app.instrumentationWatcher = watcher;
18865            app.instrumentationUiAutomationConnection = uiAutomationConnection;
18866            app.instrumentationResultClass = className;
18867            Binder.restoreCallingIdentity(origId);
18868        }
18869
18870        return true;
18871    }
18872
18873    /**
18874     * Report errors that occur while attempting to start Instrumentation.  Always writes the
18875     * error to the logs, but if somebody is watching, send the report there too.  This enables
18876     * the "am" command to report errors with more information.
18877     *
18878     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
18879     * @param cn The component name of the instrumentation.
18880     * @param report The error report.
18881     */
18882    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18883            ComponentName cn, String report) {
18884        Slog.w(TAG, report);
18885        if (watcher != null) {
18886            Bundle results = new Bundle();
18887            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18888            results.putString("Error", report);
18889            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18890        }
18891    }
18892
18893    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18894        if (app.instrumentationWatcher != null) {
18895            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18896                    app.instrumentationClass, resultCode, results);
18897        }
18898
18899        // Can't call out of the system process with a lock held, so post a message.
18900        if (app.instrumentationUiAutomationConnection != null) {
18901            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18902                    app.instrumentationUiAutomationConnection).sendToTarget();
18903        }
18904
18905        app.instrumentationWatcher = null;
18906        app.instrumentationUiAutomationConnection = null;
18907        app.instrumentationClass = null;
18908        app.instrumentationInfo = null;
18909        app.instrumentationProfileFile = null;
18910        app.instrumentationArguments = null;
18911
18912        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18913                "finished inst");
18914    }
18915
18916    public void finishInstrumentation(IApplicationThread target,
18917            int resultCode, Bundle results) {
18918        int userId = UserHandle.getCallingUserId();
18919        // Refuse possible leaked file descriptors
18920        if (results != null && results.hasFileDescriptors()) {
18921            throw new IllegalArgumentException("File descriptors passed in Intent");
18922        }
18923
18924        synchronized(this) {
18925            ProcessRecord app = getRecordForAppLocked(target);
18926            if (app == null) {
18927                Slog.w(TAG, "finishInstrumentation: no app for " + target);
18928                return;
18929            }
18930            final long origId = Binder.clearCallingIdentity();
18931            finishInstrumentationLocked(app, resultCode, results);
18932            Binder.restoreCallingIdentity(origId);
18933        }
18934    }
18935
18936    // =========================================================
18937    // CONFIGURATION
18938    // =========================================================
18939
18940    public ConfigurationInfo getDeviceConfigurationInfo() {
18941        ConfigurationInfo config = new ConfigurationInfo();
18942        synchronized (this) {
18943            final Configuration globalConfig = getGlobalConfiguration();
18944            config.reqTouchScreen = globalConfig.touchscreen;
18945            config.reqKeyboardType = globalConfig.keyboard;
18946            config.reqNavigation = globalConfig.navigation;
18947            if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
18948                    || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
18949                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18950            }
18951            if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
18952                    && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
18953                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18954            }
18955            config.reqGlEsVersion = GL_ES_VERSION;
18956        }
18957        return config;
18958    }
18959
18960    ActivityStack getFocusedStack() {
18961        return mStackSupervisor.getFocusedStack();
18962    }
18963
18964    @Override
18965    public int getFocusedStackId() throws RemoteException {
18966        ActivityStack focusedStack = getFocusedStack();
18967        if (focusedStack != null) {
18968            return focusedStack.getStackId();
18969        }
18970        return -1;
18971    }
18972
18973    public Configuration getConfiguration() {
18974        Configuration ci;
18975        synchronized(this) {
18976            ci = new Configuration(getGlobalConfiguration());
18977            ci.userSetLocale = false;
18978        }
18979        return ci;
18980    }
18981
18982    @Override
18983    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18984        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18985        synchronized (this) {
18986            mSuppressResizeConfigChanges = suppress;
18987        }
18988    }
18989
18990    @Override
18991    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18992        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18993        if (StackId.isHomeOrRecentsStack(fromStackId)) {
18994            throw new IllegalArgumentException("You can't move tasks from the home/recents stack.");
18995        }
18996        synchronized (this) {
18997            final long origId = Binder.clearCallingIdentity();
18998            try {
18999                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
19000            } finally {
19001                Binder.restoreCallingIdentity(origId);
19002            }
19003        }
19004    }
19005
19006    @Override
19007    public void updatePersistentConfiguration(Configuration values) {
19008        enforceCallingPermission(CHANGE_CONFIGURATION, "updatePersistentConfiguration()");
19009        enforceWriteSettingsPermission("updatePersistentConfiguration()");
19010        if (values == null) {
19011            throw new NullPointerException("Configuration must not be null");
19012        }
19013
19014        int userId = UserHandle.getCallingUserId();
19015
19016        synchronized(this) {
19017            updatePersistentConfigurationLocked(values, userId);
19018        }
19019    }
19020
19021    private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
19022        final long origId = Binder.clearCallingIdentity();
19023        try {
19024            updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
19025        } finally {
19026            Binder.restoreCallingIdentity(origId);
19027        }
19028    }
19029
19030    private void updateFontScaleIfNeeded(@UserIdInt int userId) {
19031        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
19032                FONT_SCALE, 1.0f, userId);
19033
19034        synchronized (this) {
19035            if (getGlobalConfiguration().fontScale == scaleFactor) {
19036                return;
19037            }
19038
19039            final Configuration configuration
19040                    = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
19041            configuration.fontScale = scaleFactor;
19042            updatePersistentConfigurationLocked(configuration, userId);
19043        }
19044    }
19045
19046    private void enforceWriteSettingsPermission(String func) {
19047        int uid = Binder.getCallingUid();
19048        if (uid == Process.ROOT_UID) {
19049            return;
19050        }
19051
19052        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
19053                Settings.getPackageNameForUid(mContext, uid), false)) {
19054            return;
19055        }
19056
19057        String msg = "Permission Denial: " + func + " from pid="
19058                + Binder.getCallingPid()
19059                + ", uid=" + uid
19060                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
19061        Slog.w(TAG, msg);
19062        throw new SecurityException(msg);
19063    }
19064
19065    @Override
19066    public boolean updateConfiguration(Configuration values) {
19067        enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
19068
19069        synchronized(this) {
19070            if (values == null && mWindowManager != null) {
19071                // sentinel: fetch the current configuration from the window manager
19072                values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
19073            }
19074
19075            if (mWindowManager != null) {
19076                // Update OOM levels based on display size.
19077                mProcessList.applyDisplaySize(mWindowManager);
19078            }
19079
19080            final long origId = Binder.clearCallingIdentity();
19081            try {
19082                if (values != null) {
19083                    Settings.System.clearConfiguration(values);
19084                }
19085                updateConfigurationLocked(values, null, false, false /* persistent */,
19086                        UserHandle.USER_NULL, false /* deferResume */,
19087                        mTmpUpdateConfigurationResult);
19088                return mTmpUpdateConfigurationResult.changes != 0;
19089            } finally {
19090                Binder.restoreCallingIdentity(origId);
19091            }
19092        }
19093    }
19094
19095    void updateUserConfigurationLocked() {
19096        final Configuration configuration = new Configuration(getGlobalConfiguration());
19097        final int currentUserId = mUserController.getCurrentUserIdLocked();
19098        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
19099                currentUserId, Settings.System.canWrite(mContext));
19100        updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
19101                false /* persistent */, currentUserId, false /* deferResume */);
19102    }
19103
19104    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
19105            boolean initLocale) {
19106        return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
19107    }
19108
19109    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
19110            boolean initLocale, boolean deferResume) {
19111        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
19112        return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
19113                UserHandle.USER_NULL, deferResume);
19114    }
19115
19116    // To cache the list of supported system locales
19117    private String[] mSupportedSystemLocales = null;
19118
19119    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
19120            boolean initLocale, boolean persistent, int userId, boolean deferResume) {
19121        return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
19122                deferResume, null /* result */);
19123    }
19124
19125    /**
19126     * Do either or both things: (1) change the current configuration, and (2)
19127     * make sure the given activity is running with the (now) current
19128     * configuration.  Returns true if the activity has been left running, or
19129     * false if <var>starting</var> is being destroyed to match the new
19130     * configuration.
19131     *
19132     * @param userId is only used when persistent parameter is set to true to persist configuration
19133     *               for that particular user
19134     */
19135    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
19136            boolean initLocale, boolean persistent, int userId, boolean deferResume,
19137            UpdateConfigurationResult result) {
19138        int changes = 0;
19139        boolean kept = true;
19140
19141        if (mWindowManager != null) {
19142            mWindowManager.deferSurfaceLayout();
19143        }
19144        try {
19145            if (values != null) {
19146                changes = updateGlobalConfiguration(values, initLocale, persistent, userId,
19147                        deferResume);
19148            }
19149
19150            kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
19151        } finally {
19152            if (mWindowManager != null) {
19153                mWindowManager.continueSurfaceLayout();
19154            }
19155        }
19156
19157        if (result != null) {
19158            result.changes = changes;
19159            result.activityRelaunched = !kept;
19160        }
19161        return kept;
19162    }
19163
19164    /** Update default (global) configuration and notify listeners about changes. */
19165    private int updateGlobalConfiguration(@NonNull Configuration values, boolean initLocale,
19166            boolean persistent, int userId, boolean deferResume) {
19167        mTempConfig.setTo(getGlobalConfiguration());
19168        final int changes = mTempConfig.updateFrom(values);
19169        if (changes == 0) {
19170            return 0;
19171        }
19172
19173        if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
19174                "Updating global configuration to: " + values);
19175
19176        EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
19177
19178        if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
19179            final LocaleList locales = values.getLocales();
19180            int bestLocaleIndex = 0;
19181            if (locales.size() > 1) {
19182                if (mSupportedSystemLocales == null) {
19183                    mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
19184                }
19185                bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
19186            }
19187            SystemProperties.set("persist.sys.locale",
19188                    locales.get(bestLocaleIndex).toLanguageTag());
19189            LocaleList.setDefault(locales, bestLocaleIndex);
19190            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
19191                    locales.get(bestLocaleIndex)));
19192        }
19193
19194        mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
19195        mTempConfig.seq = mConfigurationSeq;
19196
19197        // Update stored global config and notify everyone about the change.
19198        mStackSupervisor.onConfigurationChanged(mTempConfig);
19199
19200        Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
19201        // TODO(multi-display): Update UsageEvents#Event to include displayId.
19202        mUsageStatsService.reportConfigurationChange(mTempConfig,
19203                mUserController.getCurrentUserIdLocked());
19204
19205        // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
19206        mShowDialogs = shouldShowDialogs(mTempConfig, mInVrMode);
19207
19208        AttributeCache ac = AttributeCache.instance();
19209        if (ac != null) {
19210            ac.updateConfiguration(mTempConfig);
19211        }
19212
19213        // Make sure all resources in our process are updated right now, so that anyone who is going
19214        // to retrieve resource values after we return will be sure to get the new ones. This is
19215        // especially important during boot, where the first config change needs to guarantee all
19216        // resources have that config before following boot code is executed.
19217        mSystemThread.applyConfigurationToResources(mTempConfig);
19218
19219        // We need another copy of global config because we're scheduling some calls instead of
19220        // running them in place. We need to be sure that object we send will be handled unchanged.
19221        final Configuration configCopy = new Configuration(mTempConfig);
19222        if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
19223            Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
19224            msg.obj = configCopy;
19225            msg.arg1 = userId;
19226            mHandler.sendMessage(msg);
19227        }
19228
19229        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19230            ProcessRecord app = mLruProcesses.get(i);
19231            try {
19232                if (app.thread != null) {
19233                    if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
19234                            + app.processName + " new config " + configCopy);
19235                    app.thread.scheduleConfigurationChanged(configCopy);
19236                }
19237            } catch (Exception e) {
19238            }
19239        }
19240
19241        Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
19242        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
19243                | Intent.FLAG_RECEIVER_FOREGROUND);
19244        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
19245                AppOpsManager.OP_NONE, null, false, false, MY_PID, Process.SYSTEM_UID,
19246                UserHandle.USER_ALL);
19247        if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
19248            intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
19249            intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
19250            if (initLocale || !mProcessesReady) {
19251                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19252            }
19253            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
19254                    AppOpsManager.OP_NONE, null, false, false, MY_PID, Process.SYSTEM_UID,
19255                    UserHandle.USER_ALL);
19256        }
19257
19258        // Override configuration of the default display duplicates global config, so we need to
19259        // update it also. This will also notify WindowManager about changes.
19260        performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
19261                DEFAULT_DISPLAY);
19262
19263        return changes;
19264    }
19265
19266    @Override
19267    public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
19268        enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
19269
19270        synchronized (this) {
19271            // Check if display is initialized in AM.
19272            if (!mStackSupervisor.isDisplayAdded(displayId)) {
19273                // Call might come when display is not yet added or has already been removed.
19274                if (DEBUG_CONFIGURATION) {
19275                    Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
19276                            + displayId);
19277                }
19278                return false;
19279            }
19280
19281            if (values == null && mWindowManager != null) {
19282                // sentinel: fetch the current configuration from the window manager
19283                values = mWindowManager.computeNewConfiguration(displayId);
19284            }
19285
19286            if (mWindowManager != null) {
19287                // Update OOM levels based on display size.
19288                mProcessList.applyDisplaySize(mWindowManager);
19289            }
19290
19291            final long origId = Binder.clearCallingIdentity();
19292            try {
19293                if (values != null) {
19294                    Settings.System.clearConfiguration(values);
19295                }
19296                updateDisplayOverrideConfigurationLocked(values, null /* starting */,
19297                        false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
19298                return mTmpUpdateConfigurationResult.changes != 0;
19299            } finally {
19300                Binder.restoreCallingIdentity(origId);
19301            }
19302        }
19303    }
19304
19305    boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
19306            boolean deferResume, int displayId) {
19307        return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
19308                displayId, null /* result */);
19309    }
19310
19311    /**
19312     * Updates override configuration specific for the selected display. If no config is provided,
19313     * new one will be computed in WM based on current display info.
19314     */
19315    private boolean updateDisplayOverrideConfigurationLocked(Configuration values,
19316            ActivityRecord starting, boolean deferResume, int displayId,
19317            UpdateConfigurationResult result) {
19318        int changes = 0;
19319        boolean kept = true;
19320
19321        if (mWindowManager != null) {
19322            mWindowManager.deferSurfaceLayout();
19323        }
19324        try {
19325            if (values != null) {
19326                if (displayId == DEFAULT_DISPLAY) {
19327                    // Override configuration of the default display duplicates global config, so
19328                    // we're calling global config update instead for default display. It will also
19329                    // apply the correct override config.
19330                    changes = updateGlobalConfiguration(values, false /* initLocale */,
19331                            false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
19332                } else {
19333                    changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
19334                }
19335            }
19336
19337            kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
19338        } finally {
19339            if (mWindowManager != null) {
19340                mWindowManager.continueSurfaceLayout();
19341            }
19342        }
19343
19344        if (result != null) {
19345            result.changes = changes;
19346            result.activityRelaunched = !kept;
19347        }
19348        return kept;
19349    }
19350
19351    private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
19352            int displayId) {
19353        mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
19354        final int changes = mTempConfig.updateFrom(values);
19355        if (changes == 0) {
19356            return 0;
19357        }
19358
19359        Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " " + mTempConfig
19360                + " for displayId=" + displayId);
19361        mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
19362
19363        final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
19364        if (isDensityChange) {
19365            // Reset the unsupported display size dialog.
19366            mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
19367
19368            killAllBackgroundProcessesExcept(N, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
19369        }
19370
19371        // Update the configuration with WM first and check if any of the stacks need to be resized
19372        // due to the configuration change. If so, resize the stacks now and do any relaunches if
19373        // necessary. This way we don't need to relaunch again afterwards in
19374        // ensureActivityConfigurationLocked().
19375        if (mWindowManager != null) {
19376            final int[] resizedStacks =
19377                    mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
19378            if (resizedStacks != null) {
19379                for (int stackId : resizedStacks) {
19380                    resizeStackWithBoundsFromWindowManager(stackId, deferResume);
19381                }
19382            }
19383        }
19384
19385        return changes;
19386    }
19387
19388    /** Applies latest configuration and/or visibility updates if needed. */
19389    private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
19390        boolean kept = true;
19391        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
19392        // mainStack is null during startup.
19393        if (mainStack != null) {
19394            if (changes != 0 && starting == null) {
19395                // If the configuration changed, and the caller is not already
19396                // in the process of starting an activity, then find the top
19397                // activity to check if its configuration needs to change.
19398                starting = mainStack.topRunningActivityLocked();
19399            }
19400
19401            if (starting != null) {
19402                kept = starting.ensureActivityConfigurationLocked(changes,
19403                        false /* preserveWindow */);
19404                // And we need to make sure at this point that all other activities
19405                // are made visible with the correct configuration.
19406                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
19407                        !PRESERVE_WINDOWS);
19408            }
19409        }
19410
19411        return kept;
19412    }
19413
19414    /** Helper method that requests bounds from WM and applies them to stack. */
19415    private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
19416        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
19417        mStackSupervisor.resizeStackLocked(
19418                stackId, newBounds, null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
19419                false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
19420    }
19421
19422    /**
19423     * Decide based on the configuration whether we should show the ANR,
19424     * crash, etc dialogs.  The idea is that if there is no affordance to
19425     * press the on-screen buttons, or the user experience would be more
19426     * greatly impacted than the crash itself, we shouldn't show the dialog.
19427     *
19428     * A thought: SystemUI might also want to get told about this, the Power
19429     * dialog / global actions also might want different behaviors.
19430     */
19431    private static boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
19432        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
19433                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
19434                                   && config.navigation == Configuration.NAVIGATION_NONAV);
19435        int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
19436        final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
19437                && !(modeType == Configuration.UI_MODE_TYPE_WATCH && "user".equals(Build.TYPE)));
19438        return inputMethodExists && uiModeSupportsDialogs && !inVrMode;
19439    }
19440
19441    @Override
19442    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
19443        synchronized (this) {
19444            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
19445            if (srec != null) {
19446                return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
19447            }
19448        }
19449        return false;
19450    }
19451
19452    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
19453            Intent resultData) {
19454
19455        synchronized (this) {
19456            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
19457            if (r != null) {
19458                return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
19459            }
19460            return false;
19461        }
19462    }
19463
19464    public int getLaunchedFromUid(IBinder activityToken) {
19465        ActivityRecord srec;
19466        synchronized (this) {
19467            srec = ActivityRecord.forTokenLocked(activityToken);
19468        }
19469        if (srec == null) {
19470            return -1;
19471        }
19472        return srec.launchedFromUid;
19473    }
19474
19475    public String getLaunchedFromPackage(IBinder activityToken) {
19476        ActivityRecord srec;
19477        synchronized (this) {
19478            srec = ActivityRecord.forTokenLocked(activityToken);
19479        }
19480        if (srec == null) {
19481            return null;
19482        }
19483        return srec.launchedFromPackage;
19484    }
19485
19486    // =========================================================
19487    // LIFETIME MANAGEMENT
19488    // =========================================================
19489
19490    // Returns whether the app is receiving broadcast.
19491    // If receiving, fetch all broadcast queues which the app is
19492    // the current [or imminent] receiver on.
19493    private boolean isReceivingBroadcastLocked(ProcessRecord app,
19494            ArraySet<BroadcastQueue> receivingQueues) {
19495        if (!app.curReceivers.isEmpty()) {
19496            for (BroadcastRecord r : app.curReceivers) {
19497                receivingQueues.add(r.queue);
19498            }
19499            return true;
19500        }
19501
19502        // It's not the current receiver, but it might be starting up to become one
19503        for (BroadcastQueue queue : mBroadcastQueues) {
19504            final BroadcastRecord r = queue.mPendingBroadcast;
19505            if (r != null && r.curApp == app) {
19506                // found it; report which queue it's in
19507                receivingQueues.add(queue);
19508            }
19509        }
19510
19511        return !receivingQueues.isEmpty();
19512    }
19513
19514    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
19515            int targetUid, ComponentName targetComponent, String targetProcess) {
19516        if (!mTrackingAssociations) {
19517            return null;
19518        }
19519        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19520                = mAssociations.get(targetUid);
19521        if (components == null) {
19522            components = new ArrayMap<>();
19523            mAssociations.put(targetUid, components);
19524        }
19525        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19526        if (sourceUids == null) {
19527            sourceUids = new SparseArray<>();
19528            components.put(targetComponent, sourceUids);
19529        }
19530        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19531        if (sourceProcesses == null) {
19532            sourceProcesses = new ArrayMap<>();
19533            sourceUids.put(sourceUid, sourceProcesses);
19534        }
19535        Association ass = sourceProcesses.get(sourceProcess);
19536        if (ass == null) {
19537            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
19538                    targetProcess);
19539            sourceProcesses.put(sourceProcess, ass);
19540        }
19541        ass.mCount++;
19542        ass.mNesting++;
19543        if (ass.mNesting == 1) {
19544            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
19545            ass.mLastState = sourceState;
19546        }
19547        return ass;
19548    }
19549
19550    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
19551            ComponentName targetComponent) {
19552        if (!mTrackingAssociations) {
19553            return;
19554        }
19555        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19556                = mAssociations.get(targetUid);
19557        if (components == null) {
19558            return;
19559        }
19560        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19561        if (sourceUids == null) {
19562            return;
19563        }
19564        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19565        if (sourceProcesses == null) {
19566            return;
19567        }
19568        Association ass = sourceProcesses.get(sourceProcess);
19569        if (ass == null || ass.mNesting <= 0) {
19570            return;
19571        }
19572        ass.mNesting--;
19573        if (ass.mNesting == 0) {
19574            long uptime = SystemClock.uptimeMillis();
19575            ass.mTime += uptime - ass.mStartTime;
19576            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19577                    += uptime - ass.mLastStateUptime;
19578            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
19579        }
19580    }
19581
19582    private void noteUidProcessState(final int uid, final int state) {
19583        mBatteryStatsService.noteUidProcessState(uid, state);
19584        if (mTrackingAssociations) {
19585            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
19586                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
19587                        = mAssociations.valueAt(i1);
19588                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
19589                    SparseArray<ArrayMap<String, Association>> sourceUids
19590                            = targetComponents.valueAt(i2);
19591                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
19592                    if (sourceProcesses != null) {
19593                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
19594                            Association ass = sourceProcesses.valueAt(i4);
19595                            if (ass.mNesting >= 1) {
19596                                // currently associated
19597                                long uptime = SystemClock.uptimeMillis();
19598                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19599                                        += uptime - ass.mLastStateUptime;
19600                                ass.mLastState = state;
19601                                ass.mLastStateUptime = uptime;
19602                            }
19603                        }
19604                    }
19605                }
19606            }
19607        }
19608    }
19609
19610    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
19611            boolean doingAll, long now) {
19612        if (mAdjSeq == app.adjSeq) {
19613            // This adjustment has already been computed.
19614            return app.curRawAdj;
19615        }
19616
19617        if (app.thread == null) {
19618            app.adjSeq = mAdjSeq;
19619            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19620            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19621            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
19622        }
19623
19624        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
19625        app.adjSource = null;
19626        app.adjTarget = null;
19627        app.empty = false;
19628        app.cached = false;
19629
19630        final int activitiesSize = app.activities.size();
19631
19632        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19633            // The max adjustment doesn't allow this app to be anything
19634            // below foreground, so it is not worth doing work for it.
19635            app.adjType = "fixed";
19636            app.adjSeq = mAdjSeq;
19637            app.curRawAdj = app.maxAdj;
19638            app.foregroundActivities = false;
19639            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19640            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
19641            // System processes can do UI, and when they do we want to have
19642            // them trim their memory after the user leaves the UI.  To
19643            // facilitate this, here we need to determine whether or not it
19644            // is currently showing UI.
19645            app.systemNoUi = true;
19646            if (app == TOP_APP) {
19647                app.systemNoUi = false;
19648                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19649                app.adjType = "pers-top-activity";
19650            } else if (app.hasTopUi) {
19651                app.systemNoUi = false;
19652                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19653                app.adjType = "pers-top-ui";
19654            } else if (activitiesSize > 0) {
19655                for (int j = 0; j < activitiesSize; j++) {
19656                    final ActivityRecord r = app.activities.get(j);
19657                    if (r.visible) {
19658                        app.systemNoUi = false;
19659                    }
19660                }
19661            }
19662            if (!app.systemNoUi) {
19663                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
19664            }
19665            return (app.curAdj=app.maxAdj);
19666        }
19667
19668        app.systemNoUi = false;
19669
19670        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
19671
19672        // Determine the importance of the process, starting with most
19673        // important to least, and assign an appropriate OOM adjustment.
19674        int adj;
19675        int schedGroup;
19676        int procState;
19677        boolean foregroundActivities = false;
19678        mTmpBroadcastQueue.clear();
19679        if (app == TOP_APP) {
19680            // The last app on the list is the foreground app.
19681            adj = ProcessList.FOREGROUND_APP_ADJ;
19682            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19683            app.adjType = "top-activity";
19684            foregroundActivities = true;
19685            procState = PROCESS_STATE_CUR_TOP;
19686        } else if (app.instrumentationClass != null) {
19687            // Don't want to kill running instrumentation.
19688            adj = ProcessList.FOREGROUND_APP_ADJ;
19689            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19690            app.adjType = "instrumentation";
19691            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19692        } else if (isReceivingBroadcastLocked(app, mTmpBroadcastQueue)) {
19693            // An app that is currently receiving a broadcast also
19694            // counts as being in the foreground for OOM killer purposes.
19695            // It's placed in a sched group based on the nature of the
19696            // broadcast as reflected by which queue it's active in.
19697            adj = ProcessList.FOREGROUND_APP_ADJ;
19698            schedGroup = (mTmpBroadcastQueue.contains(mFgBroadcastQueue))
19699                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19700            app.adjType = "broadcast";
19701            procState = ActivityManager.PROCESS_STATE_RECEIVER;
19702        } else if (app.executingServices.size() > 0) {
19703            // An app that is currently executing a service callback also
19704            // counts as being in the foreground.
19705            adj = ProcessList.FOREGROUND_APP_ADJ;
19706            schedGroup = app.execServicesFg ?
19707                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19708            app.adjType = "exec-service";
19709            procState = ActivityManager.PROCESS_STATE_SERVICE;
19710            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
19711        } else {
19712            // As far as we know the process is empty.  We may change our mind later.
19713            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19714            // At this point we don't actually know the adjustment.  Use the cached adj
19715            // value that the caller wants us to.
19716            adj = cachedAdj;
19717            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19718            app.cached = true;
19719            app.empty = true;
19720            app.adjType = "cch-empty";
19721        }
19722
19723        // Examine all activities if not already foreground.
19724        if (!foregroundActivities && activitiesSize > 0) {
19725            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
19726            for (int j = 0; j < activitiesSize; j++) {
19727                final ActivityRecord r = app.activities.get(j);
19728                if (r.app != app) {
19729                    Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
19730                            + " instead of expected " + app);
19731                    if (r.app == null || (r.app.uid == app.uid)) {
19732                        // Only fix things up when they look sane
19733                        r.app = app;
19734                    } else {
19735                        continue;
19736                    }
19737                }
19738                if (r.visible) {
19739                    // App has a visible activity; only upgrade adjustment.
19740                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19741                        adj = ProcessList.VISIBLE_APP_ADJ;
19742                        app.adjType = "visible";
19743                    }
19744                    if (procState > PROCESS_STATE_CUR_TOP) {
19745                        procState = PROCESS_STATE_CUR_TOP;
19746                    }
19747                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19748                    app.cached = false;
19749                    app.empty = false;
19750                    foregroundActivities = true;
19751                    if (r.task != null && minLayer > 0) {
19752                        final int layer = r.task.mLayerRank;
19753                        if (layer >= 0 && minLayer > layer) {
19754                            minLayer = layer;
19755                        }
19756                    }
19757                    break;
19758                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
19759                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19760                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19761                        app.adjType = "pausing";
19762                    }
19763                    if (procState > PROCESS_STATE_CUR_TOP) {
19764                        procState = PROCESS_STATE_CUR_TOP;
19765                    }
19766                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19767                    app.cached = false;
19768                    app.empty = false;
19769                    foregroundActivities = true;
19770                } else if (r.state == ActivityState.STOPPING) {
19771                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19772                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19773                        app.adjType = "stopping";
19774                    }
19775                    // For the process state, we will at this point consider the
19776                    // process to be cached.  It will be cached either as an activity
19777                    // or empty depending on whether the activity is finishing.  We do
19778                    // this so that we can treat the process as cached for purposes of
19779                    // memory trimming (determing current memory level, trim command to
19780                    // send to process) since there can be an arbitrary number of stopping
19781                    // processes and they should soon all go into the cached state.
19782                    if (!r.finishing) {
19783                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19784                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19785                        }
19786                    }
19787                    app.cached = false;
19788                    app.empty = false;
19789                    foregroundActivities = true;
19790                } else {
19791                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19792                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19793                        app.adjType = "cch-act";
19794                    }
19795                }
19796            }
19797            if (adj == ProcessList.VISIBLE_APP_ADJ) {
19798                adj += minLayer;
19799            }
19800        }
19801
19802        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
19803                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
19804            if (app.foregroundServices) {
19805                // The user is aware of this app, so make it visible.
19806                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19807                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19808                app.cached = false;
19809                app.adjType = "fg-service";
19810                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19811            } else if (app.forcingToForeground != null) {
19812                // The user is aware of this app, so make it visible.
19813                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19814                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19815                app.cached = false;
19816                app.adjType = "force-fg";
19817                app.adjSource = app.forcingToForeground;
19818                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19819            }
19820        }
19821
19822        if (app == mHeavyWeightProcess) {
19823            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
19824                // We don't want to kill the current heavy-weight process.
19825                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
19826                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19827                app.cached = false;
19828                app.adjType = "heavy";
19829            }
19830            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19831                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
19832            }
19833        }
19834
19835        if (app == mHomeProcess) {
19836            if (adj > ProcessList.HOME_APP_ADJ) {
19837                // This process is hosting what we currently consider to be the
19838                // home app, so we don't want to let it go into the background.
19839                adj = ProcessList.HOME_APP_ADJ;
19840                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19841                app.cached = false;
19842                app.adjType = "home";
19843            }
19844            if (procState > ActivityManager.PROCESS_STATE_HOME) {
19845                procState = ActivityManager.PROCESS_STATE_HOME;
19846            }
19847        }
19848
19849        if (app == mPreviousProcess && app.activities.size() > 0) {
19850            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19851                // This was the previous process that showed UI to the user.
19852                // We want to try to keep it around more aggressively, to give
19853                // a good experience around switching between two apps.
19854                adj = ProcessList.PREVIOUS_APP_ADJ;
19855                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19856                app.cached = false;
19857                app.adjType = "previous";
19858            }
19859            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19860                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19861            }
19862        }
19863
19864        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
19865                + " reason=" + app.adjType);
19866
19867        // By default, we use the computed adjustment.  It may be changed if
19868        // there are applications dependent on our services or providers, but
19869        // this gives us a baseline and makes sure we don't get into an
19870        // infinite recursion.
19871        app.adjSeq = mAdjSeq;
19872        app.curRawAdj = adj;
19873        app.hasStartedServices = false;
19874
19875        if (mBackupTarget != null && app == mBackupTarget.app) {
19876            // If possible we want to avoid killing apps while they're being backed up
19877            if (adj > ProcessList.BACKUP_APP_ADJ) {
19878                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
19879                adj = ProcessList.BACKUP_APP_ADJ;
19880                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19881                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19882                }
19883                app.adjType = "backup";
19884                app.cached = false;
19885            }
19886            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
19887                procState = ActivityManager.PROCESS_STATE_BACKUP;
19888            }
19889        }
19890
19891        boolean mayBeTop = false;
19892
19893        for (int is = app.services.size()-1;
19894                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19895                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19896                        || procState > ActivityManager.PROCESS_STATE_TOP);
19897                is--) {
19898            ServiceRecord s = app.services.valueAt(is);
19899            if (s.startRequested) {
19900                app.hasStartedServices = true;
19901                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
19902                    procState = ActivityManager.PROCESS_STATE_SERVICE;
19903                }
19904                if (app.hasShownUi && app != mHomeProcess) {
19905                    // If this process has shown some UI, let it immediately
19906                    // go to the LRU list because it may be pretty heavy with
19907                    // UI stuff.  We'll tag it with a label just to help
19908                    // debug and understand what is going on.
19909                    if (adj > ProcessList.SERVICE_ADJ) {
19910                        app.adjType = "cch-started-ui-services";
19911                    }
19912                } else {
19913                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19914                        // This service has seen some activity within
19915                        // recent memory, so we will keep its process ahead
19916                        // of the background processes.
19917                        if (adj > ProcessList.SERVICE_ADJ) {
19918                            adj = ProcessList.SERVICE_ADJ;
19919                            app.adjType = "started-services";
19920                            app.cached = false;
19921                        }
19922                    }
19923                    // If we have let the service slide into the background
19924                    // state, still have some text describing what it is doing
19925                    // even though the service no longer has an impact.
19926                    if (adj > ProcessList.SERVICE_ADJ) {
19927                        app.adjType = "cch-started-services";
19928                    }
19929                }
19930            }
19931
19932            for (int conni = s.connections.size()-1;
19933                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19934                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19935                            || procState > ActivityManager.PROCESS_STATE_TOP);
19936                    conni--) {
19937                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
19938                for (int i = 0;
19939                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
19940                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19941                                || procState > ActivityManager.PROCESS_STATE_TOP);
19942                        i++) {
19943                    // XXX should compute this based on the max of
19944                    // all connected clients.
19945                    ConnectionRecord cr = clist.get(i);
19946                    if (cr.binding.client == app) {
19947                        // Binding to ourself is not interesting.
19948                        continue;
19949                    }
19950
19951                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
19952                        ProcessRecord client = cr.binding.client;
19953                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
19954                                TOP_APP, doingAll, now);
19955                        int clientProcState = client.curProcState;
19956                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19957                            // If the other app is cached for any reason, for purposes here
19958                            // we are going to consider it empty.  The specific cached state
19959                            // doesn't propagate except under certain conditions.
19960                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19961                        }
19962                        String adjType = null;
19963                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
19964                            // Not doing bind OOM management, so treat
19965                            // this guy more like a started service.
19966                            if (app.hasShownUi && app != mHomeProcess) {
19967                                // If this process has shown some UI, let it immediately
19968                                // go to the LRU list because it may be pretty heavy with
19969                                // UI stuff.  We'll tag it with a label just to help
19970                                // debug and understand what is going on.
19971                                if (adj > clientAdj) {
19972                                    adjType = "cch-bound-ui-services";
19973                                }
19974                                app.cached = false;
19975                                clientAdj = adj;
19976                                clientProcState = procState;
19977                            } else {
19978                                if (now >= (s.lastActivity
19979                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19980                                    // This service has not seen activity within
19981                                    // recent memory, so allow it to drop to the
19982                                    // LRU list if there is no other reason to keep
19983                                    // it around.  We'll also tag it with a label just
19984                                    // to help debug and undertand what is going on.
19985                                    if (adj > clientAdj) {
19986                                        adjType = "cch-bound-services";
19987                                    }
19988                                    clientAdj = adj;
19989                                }
19990                            }
19991                        }
19992                        if (adj > clientAdj) {
19993                            // If this process has recently shown UI, and
19994                            // the process that is binding to it is less
19995                            // important than being visible, then we don't
19996                            // care about the binding as much as we care
19997                            // about letting this process get into the LRU
19998                            // list to be killed and restarted if needed for
19999                            // memory.
20000                            if (app.hasShownUi && app != mHomeProcess
20001                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20002                                adjType = "cch-bound-ui-services";
20003                            } else {
20004                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
20005                                        |Context.BIND_IMPORTANT)) != 0) {
20006                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
20007                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
20008                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
20009                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
20010                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20011                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20012                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
20013                                    adj = clientAdj;
20014                                } else {
20015                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
20016                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
20017                                    }
20018                                }
20019                                if (!client.cached) {
20020                                    app.cached = false;
20021                                }
20022                                adjType = "service";
20023                            }
20024                        }
20025                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
20026                            // This will treat important bound services identically to
20027                            // the top app, which may behave differently than generic
20028                            // foreground work.
20029                            if (client.curSchedGroup > schedGroup) {
20030                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
20031                                    schedGroup = client.curSchedGroup;
20032                                } else {
20033                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20034                                }
20035                            }
20036                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
20037                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
20038                                    // Special handling of clients who are in the top state.
20039                                    // We *may* want to consider this process to be in the
20040                                    // top state as well, but only if there is not another
20041                                    // reason for it to be running.  Being on the top is a
20042                                    // special state, meaning you are specifically running
20043                                    // for the current top app.  If the process is already
20044                                    // running in the background for some other reason, it
20045                                    // is more important to continue considering it to be
20046                                    // in the background state.
20047                                    mayBeTop = true;
20048                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20049                                } else {
20050                                    // Special handling for above-top states (persistent
20051                                    // processes).  These should not bring the current process
20052                                    // into the top state, since they are not on top.  Instead
20053                                    // give them the best state after that.
20054                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
20055                                        clientProcState =
20056                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
20057                                    } else if (mWakefulness
20058                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
20059                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
20060                                                    != 0) {
20061                                        clientProcState =
20062                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
20063                                    } else {
20064                                        clientProcState =
20065                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20066                                    }
20067                                }
20068                            }
20069                        } else {
20070                            if (clientProcState <
20071                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
20072                                clientProcState =
20073                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
20074                            }
20075                        }
20076                        if (procState > clientProcState) {
20077                            procState = clientProcState;
20078                        }
20079                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20080                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
20081                            app.pendingUiClean = true;
20082                        }
20083                        if (adjType != null) {
20084                            app.adjType = adjType;
20085                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
20086                                    .REASON_SERVICE_IN_USE;
20087                            app.adjSource = cr.binding.client;
20088                            app.adjSourceProcState = clientProcState;
20089                            app.adjTarget = s.name;
20090                        }
20091                    }
20092                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
20093                        app.treatLikeActivity = true;
20094                    }
20095                    final ActivityRecord a = cr.activity;
20096                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
20097                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
20098                            (a.visible || a.state == ActivityState.RESUMED ||
20099                             a.state == ActivityState.PAUSING)) {
20100                            adj = ProcessList.FOREGROUND_APP_ADJ;
20101                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
20102                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
20103                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
20104                                } else {
20105                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20106                                }
20107                            }
20108                            app.cached = false;
20109                            app.adjType = "service";
20110                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
20111                                    .REASON_SERVICE_IN_USE;
20112                            app.adjSource = a;
20113                            app.adjSourceProcState = procState;
20114                            app.adjTarget = s.name;
20115                        }
20116                    }
20117                }
20118            }
20119        }
20120
20121        for (int provi = app.pubProviders.size()-1;
20122                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
20123                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
20124                        || procState > ActivityManager.PROCESS_STATE_TOP);
20125                provi--) {
20126            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
20127            for (int i = cpr.connections.size()-1;
20128                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
20129                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
20130                            || procState > ActivityManager.PROCESS_STATE_TOP);
20131                    i--) {
20132                ContentProviderConnection conn = cpr.connections.get(i);
20133                ProcessRecord client = conn.client;
20134                if (client == app) {
20135                    // Being our own client is not interesting.
20136                    continue;
20137                }
20138                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
20139                int clientProcState = client.curProcState;
20140                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
20141                    // If the other app is cached for any reason, for purposes here
20142                    // we are going to consider it empty.
20143                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20144                }
20145                if (adj > clientAdj) {
20146                    if (app.hasShownUi && app != mHomeProcess
20147                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20148                        app.adjType = "cch-ui-provider";
20149                    } else {
20150                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
20151                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
20152                        app.adjType = "provider";
20153                    }
20154                    app.cached &= client.cached;
20155                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
20156                            .REASON_PROVIDER_IN_USE;
20157                    app.adjSource = client;
20158                    app.adjSourceProcState = clientProcState;
20159                    app.adjTarget = cpr.name;
20160                }
20161                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
20162                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
20163                        // Special handling of clients who are in the top state.
20164                        // We *may* want to consider this process to be in the
20165                        // top state as well, but only if there is not another
20166                        // reason for it to be running.  Being on the top is a
20167                        // special state, meaning you are specifically running
20168                        // for the current top app.  If the process is already
20169                        // running in the background for some other reason, it
20170                        // is more important to continue considering it to be
20171                        // in the background state.
20172                        mayBeTop = true;
20173                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20174                    } else {
20175                        // Special handling for above-top states (persistent
20176                        // processes).  These should not bring the current process
20177                        // into the top state, since they are not on top.  Instead
20178                        // give them the best state after that.
20179                        clientProcState =
20180                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
20181                    }
20182                }
20183                if (procState > clientProcState) {
20184                    procState = clientProcState;
20185                }
20186                if (client.curSchedGroup > schedGroup) {
20187                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20188                }
20189            }
20190            // If the provider has external (non-framework) process
20191            // dependencies, ensure that its adjustment is at least
20192            // FOREGROUND_APP_ADJ.
20193            if (cpr.hasExternalProcessHandles()) {
20194                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
20195                    adj = ProcessList.FOREGROUND_APP_ADJ;
20196                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20197                    app.cached = false;
20198                    app.adjType = "provider";
20199                    app.adjTarget = cpr.name;
20200                }
20201                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20202                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20203                }
20204            }
20205        }
20206
20207        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
20208            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
20209                adj = ProcessList.PREVIOUS_APP_ADJ;
20210                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20211                app.cached = false;
20212                app.adjType = "provider";
20213            }
20214            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
20215                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
20216            }
20217        }
20218
20219        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
20220            // A client of one of our services or providers is in the top state.  We
20221            // *may* want to be in the top state, but not if we are already running in
20222            // the background for some other reason.  For the decision here, we are going
20223            // to pick out a few specific states that we want to remain in when a client
20224            // is top (states that tend to be longer-term) and otherwise allow it to go
20225            // to the top state.
20226            switch (procState) {
20227                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
20228                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
20229                case ActivityManager.PROCESS_STATE_SERVICE:
20230                    // These all are longer-term states, so pull them up to the top
20231                    // of the background states, but not all the way to the top state.
20232                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
20233                    break;
20234                default:
20235                    // Otherwise, top is a better choice, so take it.
20236                    procState = ActivityManager.PROCESS_STATE_TOP;
20237                    break;
20238            }
20239        }
20240
20241        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
20242            if (app.hasClientActivities) {
20243                // This is a cached process, but with client activities.  Mark it so.
20244                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
20245                app.adjType = "cch-client-act";
20246            } else if (app.treatLikeActivity) {
20247                // This is a cached process, but somebody wants us to treat it like it has
20248                // an activity, okay!
20249                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
20250                app.adjType = "cch-as-act";
20251            }
20252        }
20253
20254        if (adj == ProcessList.SERVICE_ADJ) {
20255            if (doingAll) {
20256                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
20257                mNewNumServiceProcs++;
20258                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
20259                if (!app.serviceb) {
20260                    // This service isn't far enough down on the LRU list to
20261                    // normally be a B service, but if we are low on RAM and it
20262                    // is large we want to force it down since we would prefer to
20263                    // keep launcher over it.
20264                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
20265                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
20266                        app.serviceHighRam = true;
20267                        app.serviceb = true;
20268                        //Slog.i(TAG, "ADJ " + app + " high ram!");
20269                    } else {
20270                        mNewNumAServiceProcs++;
20271                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
20272                    }
20273                } else {
20274                    app.serviceHighRam = false;
20275                }
20276            }
20277            if (app.serviceb) {
20278                adj = ProcessList.SERVICE_B_ADJ;
20279            }
20280        }
20281
20282        app.curRawAdj = adj;
20283
20284        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
20285        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
20286        if (adj > app.maxAdj) {
20287            adj = app.maxAdj;
20288            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
20289                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20290            }
20291        }
20292
20293        // Do final modification to adj.  Everything we do between here and applying
20294        // the final setAdj must be done in this function, because we will also use
20295        // it when computing the final cached adj later.  Note that we don't need to
20296        // worry about this for max adj above, since max adj will always be used to
20297        // keep it out of the cached vaues.
20298        app.curAdj = app.modifyRawOomAdj(adj);
20299        app.curSchedGroup = schedGroup;
20300        app.curProcState = procState;
20301        app.foregroundActivities = foregroundActivities;
20302
20303        return app.curRawAdj;
20304    }
20305
20306    /**
20307     * Record new PSS sample for a process.
20308     */
20309    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
20310            long now) {
20311        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
20312                swapPss * 1024);
20313        proc.lastPssTime = now;
20314        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
20315        if (DEBUG_PSS) Slog.d(TAG_PSS,
20316                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
20317                + " state=" + ProcessList.makeProcStateString(procState));
20318        if (proc.initialIdlePss == 0) {
20319            proc.initialIdlePss = pss;
20320        }
20321        proc.lastPss = pss;
20322        proc.lastSwapPss = swapPss;
20323        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
20324            proc.lastCachedPss = pss;
20325            proc.lastCachedSwapPss = swapPss;
20326        }
20327
20328        final SparseArray<Pair<Long, String>> watchUids
20329                = mMemWatchProcesses.getMap().get(proc.processName);
20330        Long check = null;
20331        if (watchUids != null) {
20332            Pair<Long, String> val = watchUids.get(proc.uid);
20333            if (val == null) {
20334                val = watchUids.get(0);
20335            }
20336            if (val != null) {
20337                check = val.first;
20338            }
20339        }
20340        if (check != null) {
20341            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
20342                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20343                if (!isDebuggable) {
20344                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
20345                        isDebuggable = true;
20346                    }
20347                }
20348                if (isDebuggable) {
20349                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
20350                    final ProcessRecord myProc = proc;
20351                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
20352                    mMemWatchDumpProcName = proc.processName;
20353                    mMemWatchDumpFile = heapdumpFile.toString();
20354                    mMemWatchDumpPid = proc.pid;
20355                    mMemWatchDumpUid = proc.uid;
20356                    BackgroundThread.getHandler().post(new Runnable() {
20357                        @Override
20358                        public void run() {
20359                            revokeUriPermission(ActivityThread.currentActivityThread()
20360                                            .getApplicationThread(),
20361                                    DumpHeapActivity.JAVA_URI,
20362                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
20363                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
20364                                    UserHandle.myUserId());
20365                            ParcelFileDescriptor fd = null;
20366                            try {
20367                                heapdumpFile.delete();
20368                                fd = ParcelFileDescriptor.open(heapdumpFile,
20369                                        ParcelFileDescriptor.MODE_CREATE |
20370                                                ParcelFileDescriptor.MODE_TRUNCATE |
20371                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
20372                                                ParcelFileDescriptor.MODE_APPEND);
20373                                IApplicationThread thread = myProc.thread;
20374                                if (thread != null) {
20375                                    try {
20376                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
20377                                                "Requesting dump heap from "
20378                                                + myProc + " to " + heapdumpFile);
20379                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
20380                                    } catch (RemoteException e) {
20381                                    }
20382                                }
20383                            } catch (FileNotFoundException e) {
20384                                e.printStackTrace();
20385                            } finally {
20386                                if (fd != null) {
20387                                    try {
20388                                        fd.close();
20389                                    } catch (IOException e) {
20390                                    }
20391                                }
20392                            }
20393                        }
20394                    });
20395                } else {
20396                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
20397                            + ", but debugging not enabled");
20398                }
20399            }
20400        }
20401    }
20402
20403    /**
20404     * Schedule PSS collection of a process.
20405     */
20406    void requestPssLocked(ProcessRecord proc, int procState) {
20407        if (mPendingPssProcesses.contains(proc)) {
20408            return;
20409        }
20410        if (mPendingPssProcesses.size() == 0) {
20411            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
20412        }
20413        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
20414        proc.pssProcState = procState;
20415        mPendingPssProcesses.add(proc);
20416    }
20417
20418    /**
20419     * Schedule PSS collection of all processes.
20420     */
20421    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
20422        if (!always) {
20423            if (now < (mLastFullPssTime +
20424                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
20425                return;
20426            }
20427        }
20428        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
20429        mLastFullPssTime = now;
20430        mFullPssPending = true;
20431        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
20432        mPendingPssProcesses.clear();
20433        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20434            ProcessRecord app = mLruProcesses.get(i);
20435            if (app.thread == null
20436                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
20437                continue;
20438            }
20439            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
20440                app.pssProcState = app.setProcState;
20441                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20442                        mTestPssMode, isSleepingLocked(), now);
20443                mPendingPssProcesses.add(app);
20444            }
20445        }
20446        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
20447    }
20448
20449    public void setTestPssMode(boolean enabled) {
20450        synchronized (this) {
20451            mTestPssMode = enabled;
20452            if (enabled) {
20453                // Whenever we enable the mode, we want to take a snapshot all of current
20454                // process mem use.
20455                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
20456            }
20457        }
20458    }
20459
20460    /**
20461     * Ask a given process to GC right now.
20462     */
20463    final void performAppGcLocked(ProcessRecord app) {
20464        try {
20465            app.lastRequestedGc = SystemClock.uptimeMillis();
20466            if (app.thread != null) {
20467                if (app.reportLowMemory) {
20468                    app.reportLowMemory = false;
20469                    app.thread.scheduleLowMemory();
20470                } else {
20471                    app.thread.processInBackground();
20472                }
20473            }
20474        } catch (Exception e) {
20475            // whatever.
20476        }
20477    }
20478
20479    /**
20480     * Returns true if things are idle enough to perform GCs.
20481     */
20482    private final boolean canGcNowLocked() {
20483        boolean processingBroadcasts = false;
20484        for (BroadcastQueue q : mBroadcastQueues) {
20485            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
20486                processingBroadcasts = true;
20487            }
20488        }
20489        return !processingBroadcasts
20490                && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
20491    }
20492
20493    /**
20494     * Perform GCs on all processes that are waiting for it, but only
20495     * if things are idle.
20496     */
20497    final void performAppGcsLocked() {
20498        final int N = mProcessesToGc.size();
20499        if (N <= 0) {
20500            return;
20501        }
20502        if (canGcNowLocked()) {
20503            while (mProcessesToGc.size() > 0) {
20504                ProcessRecord proc = mProcessesToGc.remove(0);
20505                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
20506                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
20507                            <= SystemClock.uptimeMillis()) {
20508                        // To avoid spamming the system, we will GC processes one
20509                        // at a time, waiting a few seconds between each.
20510                        performAppGcLocked(proc);
20511                        scheduleAppGcsLocked();
20512                        return;
20513                    } else {
20514                        // It hasn't been long enough since we last GCed this
20515                        // process...  put it in the list to wait for its time.
20516                        addProcessToGcListLocked(proc);
20517                        break;
20518                    }
20519                }
20520            }
20521
20522            scheduleAppGcsLocked();
20523        }
20524    }
20525
20526    /**
20527     * If all looks good, perform GCs on all processes waiting for them.
20528     */
20529    final void performAppGcsIfAppropriateLocked() {
20530        if (canGcNowLocked()) {
20531            performAppGcsLocked();
20532            return;
20533        }
20534        // Still not idle, wait some more.
20535        scheduleAppGcsLocked();
20536    }
20537
20538    /**
20539     * Schedule the execution of all pending app GCs.
20540     */
20541    final void scheduleAppGcsLocked() {
20542        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
20543
20544        if (mProcessesToGc.size() > 0) {
20545            // Schedule a GC for the time to the next process.
20546            ProcessRecord proc = mProcessesToGc.get(0);
20547            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
20548
20549            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
20550            long now = SystemClock.uptimeMillis();
20551            if (when < (now+GC_TIMEOUT)) {
20552                when = now + GC_TIMEOUT;
20553            }
20554            mHandler.sendMessageAtTime(msg, when);
20555        }
20556    }
20557
20558    /**
20559     * Add a process to the array of processes waiting to be GCed.  Keeps the
20560     * list in sorted order by the last GC time.  The process can't already be
20561     * on the list.
20562     */
20563    final void addProcessToGcListLocked(ProcessRecord proc) {
20564        boolean added = false;
20565        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
20566            if (mProcessesToGc.get(i).lastRequestedGc <
20567                    proc.lastRequestedGc) {
20568                added = true;
20569                mProcessesToGc.add(i+1, proc);
20570                break;
20571            }
20572        }
20573        if (!added) {
20574            mProcessesToGc.add(0, proc);
20575        }
20576    }
20577
20578    /**
20579     * Set up to ask a process to GC itself.  This will either do it
20580     * immediately, or put it on the list of processes to gc the next
20581     * time things are idle.
20582     */
20583    final void scheduleAppGcLocked(ProcessRecord app) {
20584        long now = SystemClock.uptimeMillis();
20585        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
20586            return;
20587        }
20588        if (!mProcessesToGc.contains(app)) {
20589            addProcessToGcListLocked(app);
20590            scheduleAppGcsLocked();
20591        }
20592    }
20593
20594    final void checkExcessivePowerUsageLocked(boolean doKills) {
20595        updateCpuStatsNow();
20596
20597        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20598        boolean doWakeKills = doKills;
20599        boolean doCpuKills = doKills;
20600        if (mLastPowerCheckRealtime == 0) {
20601            doWakeKills = false;
20602        }
20603        if (mLastPowerCheckUptime == 0) {
20604            doCpuKills = false;
20605        }
20606        if (stats.isScreenOn()) {
20607            doWakeKills = false;
20608        }
20609        final long curRealtime = SystemClock.elapsedRealtime();
20610        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
20611        final long curUptime = SystemClock.uptimeMillis();
20612        final long uptimeSince = curUptime - mLastPowerCheckUptime;
20613        mLastPowerCheckRealtime = curRealtime;
20614        mLastPowerCheckUptime = curUptime;
20615        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
20616            doWakeKills = false;
20617        }
20618        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
20619            doCpuKills = false;
20620        }
20621        int i = mLruProcesses.size();
20622        while (i > 0) {
20623            i--;
20624            ProcessRecord app = mLruProcesses.get(i);
20625            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20626                long wtime;
20627                synchronized (stats) {
20628                    wtime = stats.getProcessWakeTime(app.info.uid,
20629                            app.pid, curRealtime);
20630                }
20631                long wtimeUsed = wtime - app.lastWakeTime;
20632                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
20633                if (DEBUG_POWER) {
20634                    StringBuilder sb = new StringBuilder(128);
20635                    sb.append("Wake for ");
20636                    app.toShortString(sb);
20637                    sb.append(": over ");
20638                    TimeUtils.formatDuration(realtimeSince, sb);
20639                    sb.append(" used ");
20640                    TimeUtils.formatDuration(wtimeUsed, sb);
20641                    sb.append(" (");
20642                    sb.append((wtimeUsed*100)/realtimeSince);
20643                    sb.append("%)");
20644                    Slog.i(TAG_POWER, sb.toString());
20645                    sb.setLength(0);
20646                    sb.append("CPU for ");
20647                    app.toShortString(sb);
20648                    sb.append(": over ");
20649                    TimeUtils.formatDuration(uptimeSince, sb);
20650                    sb.append(" used ");
20651                    TimeUtils.formatDuration(cputimeUsed, sb);
20652                    sb.append(" (");
20653                    sb.append((cputimeUsed*100)/uptimeSince);
20654                    sb.append("%)");
20655                    Slog.i(TAG_POWER, sb.toString());
20656                }
20657                // If a process has held a wake lock for more
20658                // than 50% of the time during this period,
20659                // that sounds bad.  Kill!
20660                if (doWakeKills && realtimeSince > 0
20661                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
20662                    synchronized (stats) {
20663                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
20664                                realtimeSince, wtimeUsed);
20665                    }
20666                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
20667                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
20668                } else if (doCpuKills && uptimeSince > 0
20669                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
20670                    synchronized (stats) {
20671                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
20672                                uptimeSince, cputimeUsed);
20673                    }
20674                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
20675                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
20676                } else {
20677                    app.lastWakeTime = wtime;
20678                    app.lastCpuTime = app.curCpuTime;
20679                }
20680            }
20681        }
20682    }
20683
20684    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
20685            long nowElapsed) {
20686        boolean success = true;
20687
20688        if (app.curRawAdj != app.setRawAdj) {
20689            app.setRawAdj = app.curRawAdj;
20690        }
20691
20692        int changes = 0;
20693
20694        if (app.curAdj != app.setAdj) {
20695            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
20696            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20697                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
20698                    + app.adjType);
20699            app.setAdj = app.curAdj;
20700            app.verifiedAdj = ProcessList.INVALID_ADJ;
20701        }
20702
20703        if (app.setSchedGroup != app.curSchedGroup) {
20704            int oldSchedGroup = app.setSchedGroup;
20705            app.setSchedGroup = app.curSchedGroup;
20706            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20707                    "Setting sched group of " + app.processName
20708                    + " to " + app.curSchedGroup);
20709            if (app.waitingToKill != null && app.curReceivers.isEmpty()
20710                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
20711                app.kill(app.waitingToKill, true);
20712                success = false;
20713            } else {
20714                int processGroup;
20715                switch (app.curSchedGroup) {
20716                    case ProcessList.SCHED_GROUP_BACKGROUND:
20717                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
20718                        break;
20719                    case ProcessList.SCHED_GROUP_TOP_APP:
20720                    case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
20721                        processGroup = Process.THREAD_GROUP_TOP_APP;
20722                        break;
20723                    default:
20724                        processGroup = Process.THREAD_GROUP_DEFAULT;
20725                        break;
20726                }
20727                long oldId = Binder.clearCallingIdentity();
20728                try {
20729                    Process.setProcessGroup(app.pid, processGroup);
20730                    if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
20731                        // do nothing if we already switched to RT
20732                        if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
20733                            // Switch VR thread for app to SCHED_FIFO
20734                            if (mInVrMode && app.vrThreadTid != 0) {
20735                                try {
20736                                    Process.setThreadScheduler(app.vrThreadTid,
20737                                        Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20738                                } catch (IllegalArgumentException e) {
20739                                    // thread died, ignore
20740                                }
20741                            }
20742                            if (mUseFifoUiScheduling) {
20743                                // Switch UI pipeline for app to SCHED_FIFO
20744                                app.savedPriority = Process.getThreadPriority(app.pid);
20745                                try {
20746                                    Process.setThreadScheduler(app.pid,
20747                                        Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20748                                } catch (IllegalArgumentException e) {
20749                                    // thread died, ignore
20750                                }
20751                                if (app.renderThreadTid != 0) {
20752                                    try {
20753                                        Process.setThreadScheduler(app.renderThreadTid,
20754                                            Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20755                                    } catch (IllegalArgumentException e) {
20756                                        // thread died, ignore
20757                                    }
20758                                    if (DEBUG_OOM_ADJ) {
20759                                        Slog.d("UI_FIFO", "Set RenderThread (TID " +
20760                                            app.renderThreadTid + ") to FIFO");
20761                                    }
20762                                } else {
20763                                    if (DEBUG_OOM_ADJ) {
20764                                        Slog.d("UI_FIFO", "Not setting RenderThread TID");
20765                                    }
20766                                }
20767                            } else {
20768                                // Boost priority for top app UI and render threads
20769                                Process.setThreadPriority(app.pid, -10);
20770                                if (app.renderThreadTid != 0) {
20771                                    try {
20772                                        Process.setThreadPriority(app.renderThreadTid, -10);
20773                                    } catch (IllegalArgumentException e) {
20774                                        // thread died, ignore
20775                                    }
20776                                }
20777                            }
20778                        }
20779                    } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
20780                               app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
20781                        // Reset VR thread to SCHED_OTHER
20782                        // Safe to do even if we're not in VR mode
20783                        if (app.vrThreadTid != 0) {
20784                            Process.setThreadScheduler(app.vrThreadTid, Process.SCHED_OTHER, 0);
20785                        }
20786                        if (mUseFifoUiScheduling) {
20787                            // Reset UI pipeline to SCHED_OTHER
20788                            Process.setThreadScheduler(app.pid, Process.SCHED_OTHER, 0);
20789                            Process.setThreadPriority(app.pid, app.savedPriority);
20790                            if (app.renderThreadTid != 0) {
20791                                Process.setThreadScheduler(app.renderThreadTid,
20792                                    Process.SCHED_OTHER, 0);
20793                                Process.setThreadPriority(app.renderThreadTid, -4);
20794                            }
20795                        } else {
20796                            // Reset priority for top app UI and render threads
20797                            Process.setThreadPriority(app.pid, 0);
20798                            if (app.renderThreadTid != 0) {
20799                                Process.setThreadPriority(app.renderThreadTid, 0);
20800                            }
20801                        }
20802                    }
20803                } catch (Exception e) {
20804                    Slog.w(TAG, "Failed setting process group of " + app.pid
20805                            + " to " + app.curSchedGroup);
20806                    e.printStackTrace();
20807                } finally {
20808                    Binder.restoreCallingIdentity(oldId);
20809                }
20810            }
20811        }
20812        if (app.repForegroundActivities != app.foregroundActivities) {
20813            app.repForegroundActivities = app.foregroundActivities;
20814            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
20815        }
20816        if (app.repProcState != app.curProcState) {
20817            app.repProcState = app.curProcState;
20818            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
20819            if (app.thread != null) {
20820                try {
20821                    if (false) {
20822                        //RuntimeException h = new RuntimeException("here");
20823                        Slog.i(TAG, "Sending new process state " + app.repProcState
20824                                + " to " + app /*, h*/);
20825                    }
20826                    app.thread.setProcessState(app.repProcState);
20827                } catch (RemoteException e) {
20828                }
20829            }
20830        }
20831        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
20832                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
20833            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
20834                // Experimental code to more aggressively collect pss while
20835                // running test...  the problem is that this tends to collect
20836                // the data right when a process is transitioning between process
20837                // states, which well tend to give noisy data.
20838                long start = SystemClock.uptimeMillis();
20839                long pss = Debug.getPss(app.pid, mTmpLong, null);
20840                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
20841                mPendingPssProcesses.remove(app);
20842                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
20843                        + " to " + app.curProcState + ": "
20844                        + (SystemClock.uptimeMillis()-start) + "ms");
20845            }
20846            app.lastStateTime = now;
20847            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20848                    mTestPssMode, isSleepingLocked(), now);
20849            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
20850                    + ProcessList.makeProcStateString(app.setProcState) + " to "
20851                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
20852                    + (app.nextPssTime-now) + ": " + app);
20853        } else {
20854            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
20855                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
20856                    mTestPssMode)))) {
20857                requestPssLocked(app, app.setProcState);
20858                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
20859                        mTestPssMode, isSleepingLocked(), now);
20860            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
20861                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
20862        }
20863        if (app.setProcState != app.curProcState) {
20864            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20865                    "Proc state change of " + app.processName
20866                            + " to " + app.curProcState);
20867            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
20868            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
20869            if (setImportant && !curImportant) {
20870                // This app is no longer something we consider important enough to allow to
20871                // use arbitrary amounts of battery power.  Note
20872                // its current wake lock time to later know to kill it if
20873                // it is not behaving well.
20874                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20875                synchronized (stats) {
20876                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
20877                            app.pid, nowElapsed);
20878                }
20879                app.lastCpuTime = app.curCpuTime;
20880
20881            }
20882            // Inform UsageStats of important process state change
20883            // Must be called before updating setProcState
20884            maybeUpdateUsageStatsLocked(app, nowElapsed);
20885
20886            app.setProcState = app.curProcState;
20887            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20888                app.notCachedSinceIdle = false;
20889            }
20890            if (!doingAll) {
20891                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
20892            } else {
20893                app.procStateChanged = true;
20894            }
20895        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
20896                > USAGE_STATS_INTERACTION_INTERVAL) {
20897            // For apps that sit around for a long time in the interactive state, we need
20898            // to report this at least once a day so they don't go idle.
20899            maybeUpdateUsageStatsLocked(app, nowElapsed);
20900        }
20901
20902        if (changes != 0) {
20903            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20904                    "Changes in " + app + ": " + changes);
20905            int i = mPendingProcessChanges.size()-1;
20906            ProcessChangeItem item = null;
20907            while (i >= 0) {
20908                item = mPendingProcessChanges.get(i);
20909                if (item.pid == app.pid) {
20910                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20911                            "Re-using existing item: " + item);
20912                    break;
20913                }
20914                i--;
20915            }
20916            if (i < 0) {
20917                // No existing item in pending changes; need a new one.
20918                final int NA = mAvailProcessChanges.size();
20919                if (NA > 0) {
20920                    item = mAvailProcessChanges.remove(NA-1);
20921                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20922                            "Retrieving available item: " + item);
20923                } else {
20924                    item = new ProcessChangeItem();
20925                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20926                            "Allocating new item: " + item);
20927                }
20928                item.changes = 0;
20929                item.pid = app.pid;
20930                item.uid = app.info.uid;
20931                if (mPendingProcessChanges.size() == 0) {
20932                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20933                            "*** Enqueueing dispatch processes changed!");
20934                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
20935                }
20936                mPendingProcessChanges.add(item);
20937            }
20938            item.changes |= changes;
20939            item.processState = app.repProcState;
20940            item.foregroundActivities = app.repForegroundActivities;
20941            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20942                    "Item " + Integer.toHexString(System.identityHashCode(item))
20943                    + " " + app.toShortString() + ": changes=" + item.changes
20944                    + " procState=" + item.processState
20945                    + " foreground=" + item.foregroundActivities
20946                    + " type=" + app.adjType + " source=" + app.adjSource
20947                    + " target=" + app.adjTarget);
20948        }
20949
20950        return success;
20951    }
20952
20953    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
20954        final UidRecord.ChangeItem pendingChange;
20955        if (uidRec == null || uidRec.pendingChange == null) {
20956            if (mPendingUidChanges.size() == 0) {
20957                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20958                        "*** Enqueueing dispatch uid changed!");
20959                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
20960            }
20961            final int NA = mAvailUidChanges.size();
20962            if (NA > 0) {
20963                pendingChange = mAvailUidChanges.remove(NA-1);
20964                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20965                        "Retrieving available item: " + pendingChange);
20966            } else {
20967                pendingChange = new UidRecord.ChangeItem();
20968                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20969                        "Allocating new item: " + pendingChange);
20970            }
20971            if (uidRec != null) {
20972                uidRec.pendingChange = pendingChange;
20973                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
20974                    // If this uid is going away, and we haven't yet reported it is gone,
20975                    // then do so now.
20976                    change = UidRecord.CHANGE_GONE_IDLE;
20977                }
20978            } else if (uid < 0) {
20979                throw new IllegalArgumentException("No UidRecord or uid");
20980            }
20981            pendingChange.uidRecord = uidRec;
20982            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
20983            mPendingUidChanges.add(pendingChange);
20984        } else {
20985            pendingChange = uidRec.pendingChange;
20986            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
20987                change = UidRecord.CHANGE_GONE_IDLE;
20988            }
20989        }
20990        pendingChange.change = change;
20991        pendingChange.processState = uidRec != null
20992                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
20993        pendingChange.ephemeral = uidRec.ephemeral;
20994
20995        // Directly update the power manager, since we sit on top of it and it is critical
20996        // it be kept in sync (so wake locks will be held as soon as appropriate).
20997        if (mLocalPowerManager != null) {
20998            switch (change) {
20999                case UidRecord.CHANGE_GONE:
21000                case UidRecord.CHANGE_GONE_IDLE:
21001                    mLocalPowerManager.uidGone(pendingChange.uid);
21002                    break;
21003                case UidRecord.CHANGE_IDLE:
21004                    mLocalPowerManager.uidIdle(pendingChange.uid);
21005                    break;
21006                case UidRecord.CHANGE_ACTIVE:
21007                    mLocalPowerManager.uidActive(pendingChange.uid);
21008                    break;
21009                default:
21010                    mLocalPowerManager.updateUidProcState(pendingChange.uid,
21011                            pendingChange.processState);
21012                    break;
21013            }
21014        }
21015    }
21016
21017    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
21018            String authority) {
21019        if (app == null) return;
21020        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
21021            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
21022            if (userState == null) return;
21023            final long now = SystemClock.elapsedRealtime();
21024            Long lastReported = userState.mProviderLastReportedFg.get(authority);
21025            if (lastReported == null || lastReported < now - 60 * 1000L) {
21026                if (mSystemReady) {
21027                    // Cannot touch the user stats if not system ready
21028                    mUsageStatsService.reportContentProviderUsage(
21029                            authority, providerPkgName, app.userId);
21030                }
21031                userState.mProviderLastReportedFg.put(authority, now);
21032            }
21033        }
21034    }
21035
21036    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
21037        if (DEBUG_USAGE_STATS) {
21038            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
21039                    + "] state changes: old = " + app.setProcState + ", new = "
21040                    + app.curProcState);
21041        }
21042        if (mUsageStatsService == null) {
21043            return;
21044        }
21045        boolean isInteraction;
21046        // To avoid some abuse patterns, we are going to be careful about what we consider
21047        // to be an app interaction.  Being the top activity doesn't count while the display
21048        // is sleeping, nor do short foreground services.
21049        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
21050            isInteraction = true;
21051            app.fgInteractionTime = 0;
21052        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
21053            if (app.fgInteractionTime == 0) {
21054                app.fgInteractionTime = nowElapsed;
21055                isInteraction = false;
21056            } else {
21057                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
21058            }
21059        } else {
21060            // If the app was being forced to the foreground, by say a Toast, then
21061            // no need to treat it as an interaction
21062            isInteraction = app.forcingToForeground == null
21063                    && app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21064            app.fgInteractionTime = 0;
21065        }
21066        if (isInteraction && (!app.reportedInteraction
21067                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
21068            app.interactionEventTime = nowElapsed;
21069            String[] packages = app.getPackageList();
21070            if (packages != null) {
21071                for (int i = 0; i < packages.length; i++) {
21072                    mUsageStatsService.reportEvent(packages[i], app.userId,
21073                            UsageEvents.Event.SYSTEM_INTERACTION);
21074                }
21075            }
21076        }
21077        app.reportedInteraction = isInteraction;
21078        if (!isInteraction) {
21079            app.interactionEventTime = 0;
21080        }
21081    }
21082
21083    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
21084        if (proc.thread != null) {
21085            if (proc.baseProcessTracker != null) {
21086                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
21087            }
21088        }
21089    }
21090
21091    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
21092            ProcessRecord TOP_APP, boolean doingAll, long now) {
21093        if (app.thread == null) {
21094            return false;
21095        }
21096
21097        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
21098
21099        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
21100    }
21101
21102    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
21103            boolean oomAdj) {
21104        if (isForeground != proc.foregroundServices) {
21105            proc.foregroundServices = isForeground;
21106            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
21107                    proc.info.uid);
21108            if (isForeground) {
21109                if (curProcs == null) {
21110                    curProcs = new ArrayList<ProcessRecord>();
21111                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
21112                }
21113                if (!curProcs.contains(proc)) {
21114                    curProcs.add(proc);
21115                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
21116                            proc.info.packageName, proc.info.uid);
21117                }
21118            } else {
21119                if (curProcs != null) {
21120                    if (curProcs.remove(proc)) {
21121                        mBatteryStatsService.noteEvent(
21122                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
21123                                proc.info.packageName, proc.info.uid);
21124                        if (curProcs.size() <= 0) {
21125                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
21126                        }
21127                    }
21128                }
21129            }
21130            if (oomAdj) {
21131                updateOomAdjLocked();
21132            }
21133        }
21134    }
21135
21136    private final ActivityRecord resumedAppLocked() {
21137        ActivityRecord act = mStackSupervisor.getResumedActivityLocked();
21138        String pkg;
21139        int uid;
21140        if (act != null) {
21141            pkg = act.packageName;
21142            uid = act.info.applicationInfo.uid;
21143        } else {
21144            pkg = null;
21145            uid = -1;
21146        }
21147        // Has the UID or resumed package name changed?
21148        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
21149                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
21150            if (mCurResumedPackage != null) {
21151                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
21152                        mCurResumedPackage, mCurResumedUid);
21153            }
21154            mCurResumedPackage = pkg;
21155            mCurResumedUid = uid;
21156            if (mCurResumedPackage != null) {
21157                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
21158                        mCurResumedPackage, mCurResumedUid);
21159            }
21160        }
21161        return act;
21162    }
21163
21164    final boolean updateOomAdjLocked(ProcessRecord app) {
21165        final ActivityRecord TOP_ACT = resumedAppLocked();
21166        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
21167        final boolean wasCached = app.cached;
21168
21169        mAdjSeq++;
21170
21171        // This is the desired cached adjusment we want to tell it to use.
21172        // If our app is currently cached, we know it, and that is it.  Otherwise,
21173        // we don't know it yet, and it needs to now be cached we will then
21174        // need to do a complete oom adj.
21175        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
21176                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
21177        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
21178                SystemClock.uptimeMillis());
21179        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
21180            // Changed to/from cached state, so apps after it in the LRU
21181            // list may also be changed.
21182            updateOomAdjLocked();
21183        }
21184        return success;
21185    }
21186
21187    final void updateOomAdjLocked() {
21188        final ActivityRecord TOP_ACT = resumedAppLocked();
21189        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
21190        final long now = SystemClock.uptimeMillis();
21191        final long nowElapsed = SystemClock.elapsedRealtime();
21192        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
21193        final int N = mLruProcesses.size();
21194
21195        if (false) {
21196            RuntimeException e = new RuntimeException();
21197            e.fillInStackTrace();
21198            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
21199        }
21200
21201        // Reset state in all uid records.
21202        for (int i=mActiveUids.size()-1; i>=0; i--) {
21203            final UidRecord uidRec = mActiveUids.valueAt(i);
21204            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21205                    "Starting update of " + uidRec);
21206            uidRec.reset();
21207        }
21208
21209        mStackSupervisor.rankTaskLayersIfNeeded();
21210
21211        mAdjSeq++;
21212        mNewNumServiceProcs = 0;
21213        mNewNumAServiceProcs = 0;
21214
21215        final int emptyProcessLimit;
21216        final int cachedProcessLimit;
21217        if (mProcessLimit <= 0) {
21218            emptyProcessLimit = cachedProcessLimit = 0;
21219        } else if (mProcessLimit == 1) {
21220            emptyProcessLimit = 1;
21221            cachedProcessLimit = 0;
21222        } else {
21223            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
21224            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
21225        }
21226
21227        // Let's determine how many processes we have running vs.
21228        // how many slots we have for background processes; we may want
21229        // to put multiple processes in a slot of there are enough of
21230        // them.
21231        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
21232                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
21233        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
21234        if (numEmptyProcs > cachedProcessLimit) {
21235            // If there are more empty processes than our limit on cached
21236            // processes, then use the cached process limit for the factor.
21237            // This ensures that the really old empty processes get pushed
21238            // down to the bottom, so if we are running low on memory we will
21239            // have a better chance at keeping around more cached processes
21240            // instead of a gazillion empty processes.
21241            numEmptyProcs = cachedProcessLimit;
21242        }
21243        int emptyFactor = numEmptyProcs/numSlots;
21244        if (emptyFactor < 1) emptyFactor = 1;
21245        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
21246        if (cachedFactor < 1) cachedFactor = 1;
21247        int stepCached = 0;
21248        int stepEmpty = 0;
21249        int numCached = 0;
21250        int numEmpty = 0;
21251        int numTrimming = 0;
21252
21253        mNumNonCachedProcs = 0;
21254        mNumCachedHiddenProcs = 0;
21255
21256        // First update the OOM adjustment for each of the
21257        // application processes based on their current state.
21258        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
21259        int nextCachedAdj = curCachedAdj+1;
21260        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
21261        int nextEmptyAdj = curEmptyAdj+2;
21262        for (int i=N-1; i>=0; i--) {
21263            ProcessRecord app = mLruProcesses.get(i);
21264            if (!app.killedByAm && app.thread != null) {
21265                app.procStateChanged = false;
21266                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
21267
21268                // If we haven't yet assigned the final cached adj
21269                // to the process, do that now.
21270                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
21271                    switch (app.curProcState) {
21272                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
21273                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
21274                            // This process is a cached process holding activities...
21275                            // assign it the next cached value for that type, and then
21276                            // step that cached level.
21277                            app.curRawAdj = curCachedAdj;
21278                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
21279                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
21280                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
21281                                    + ")");
21282                            if (curCachedAdj != nextCachedAdj) {
21283                                stepCached++;
21284                                if (stepCached >= cachedFactor) {
21285                                    stepCached = 0;
21286                                    curCachedAdj = nextCachedAdj;
21287                                    nextCachedAdj += 2;
21288                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
21289                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
21290                                    }
21291                                }
21292                            }
21293                            break;
21294                        default:
21295                            // For everything else, assign next empty cached process
21296                            // level and bump that up.  Note that this means that
21297                            // long-running services that have dropped down to the
21298                            // cached level will be treated as empty (since their process
21299                            // state is still as a service), which is what we want.
21300                            app.curRawAdj = curEmptyAdj;
21301                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
21302                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
21303                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
21304                                    + ")");
21305                            if (curEmptyAdj != nextEmptyAdj) {
21306                                stepEmpty++;
21307                                if (stepEmpty >= emptyFactor) {
21308                                    stepEmpty = 0;
21309                                    curEmptyAdj = nextEmptyAdj;
21310                                    nextEmptyAdj += 2;
21311                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
21312                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
21313                                    }
21314                                }
21315                            }
21316                            break;
21317                    }
21318                }
21319
21320                applyOomAdjLocked(app, true, now, nowElapsed);
21321
21322                // Count the number of process types.
21323                switch (app.curProcState) {
21324                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
21325                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
21326                        mNumCachedHiddenProcs++;
21327                        numCached++;
21328                        if (numCached > cachedProcessLimit) {
21329                            app.kill("cached #" + numCached, true);
21330                        }
21331                        break;
21332                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
21333                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
21334                                && app.lastActivityTime < oldTime) {
21335                            app.kill("empty for "
21336                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
21337                                    / 1000) + "s", true);
21338                        } else {
21339                            numEmpty++;
21340                            if (numEmpty > emptyProcessLimit) {
21341                                app.kill("empty #" + numEmpty, true);
21342                            }
21343                        }
21344                        break;
21345                    default:
21346                        mNumNonCachedProcs++;
21347                        break;
21348                }
21349
21350                if (app.isolated && app.services.size() <= 0) {
21351                    // If this is an isolated process, and there are no
21352                    // services running in it, then the process is no longer
21353                    // needed.  We agressively kill these because we can by
21354                    // definition not re-use the same process again, and it is
21355                    // good to avoid having whatever code was running in them
21356                    // left sitting around after no longer needed.
21357                    app.kill("isolated not needed", true);
21358                } else {
21359                    // Keeping this process, update its uid.
21360                    final UidRecord uidRec = app.uidRecord;
21361                    if (uidRec != null) {
21362                        uidRec.ephemeral = app.info.isEphemeralApp();
21363                        if (uidRec.curProcState > app.curProcState) {
21364                            uidRec.curProcState = app.curProcState;
21365                        }
21366                    }
21367                }
21368
21369                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
21370                        && !app.killedByAm) {
21371                    numTrimming++;
21372                }
21373            }
21374        }
21375
21376        mNumServiceProcs = mNewNumServiceProcs;
21377
21378        // Now determine the memory trimming level of background processes.
21379        // Unfortunately we need to start at the back of the list to do this
21380        // properly.  We only do this if the number of background apps we
21381        // are managing to keep around is less than half the maximum we desire;
21382        // if we are keeping a good number around, we'll let them use whatever
21383        // memory they want.
21384        final int numCachedAndEmpty = numCached + numEmpty;
21385        int memFactor;
21386        if (numCached <= ProcessList.TRIM_CACHED_APPS
21387                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
21388            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
21389                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
21390            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
21391                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
21392            } else {
21393                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
21394            }
21395        } else {
21396            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
21397        }
21398        // We always allow the memory level to go up (better).  We only allow it to go
21399        // down if we are in a state where that is allowed, *and* the total number of processes
21400        // has gone down since last time.
21401        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
21402                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
21403                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
21404        if (memFactor > mLastMemoryLevel) {
21405            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
21406                memFactor = mLastMemoryLevel;
21407                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
21408            }
21409        }
21410        if (memFactor != mLastMemoryLevel) {
21411            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
21412        }
21413        mLastMemoryLevel = memFactor;
21414        mLastNumProcesses = mLruProcesses.size();
21415        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
21416        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
21417        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
21418            if (mLowRamStartTime == 0) {
21419                mLowRamStartTime = now;
21420            }
21421            int step = 0;
21422            int fgTrimLevel;
21423            switch (memFactor) {
21424                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
21425                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
21426                    break;
21427                case ProcessStats.ADJ_MEM_FACTOR_LOW:
21428                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
21429                    break;
21430                default:
21431                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
21432                    break;
21433            }
21434            int factor = numTrimming/3;
21435            int minFactor = 2;
21436            if (mHomeProcess != null) minFactor++;
21437            if (mPreviousProcess != null) minFactor++;
21438            if (factor < minFactor) factor = minFactor;
21439            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
21440            for (int i=N-1; i>=0; i--) {
21441                ProcessRecord app = mLruProcesses.get(i);
21442                if (allChanged || app.procStateChanged) {
21443                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
21444                    app.procStateChanged = false;
21445                }
21446                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
21447                        && !app.killedByAm) {
21448                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
21449                        try {
21450                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21451                                    "Trimming memory of " + app.processName + " to " + curLevel);
21452                            app.thread.scheduleTrimMemory(curLevel);
21453                        } catch (RemoteException e) {
21454                        }
21455                        if (false) {
21456                            // For now we won't do this; our memory trimming seems
21457                            // to be good enough at this point that destroying
21458                            // activities causes more harm than good.
21459                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
21460                                    && app != mHomeProcess && app != mPreviousProcess) {
21461                                // Need to do this on its own message because the stack may not
21462                                // be in a consistent state at this point.
21463                                // For these apps we will also finish their activities
21464                                // to help them free memory.
21465                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
21466                            }
21467                        }
21468                    }
21469                    app.trimMemoryLevel = curLevel;
21470                    step++;
21471                    if (step >= factor) {
21472                        step = 0;
21473                        switch (curLevel) {
21474                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
21475                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
21476                                break;
21477                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
21478                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
21479                                break;
21480                        }
21481                    }
21482                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
21483                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
21484                            && app.thread != null) {
21485                        try {
21486                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21487                                    "Trimming memory of heavy-weight " + app.processName
21488                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
21489                            app.thread.scheduleTrimMemory(
21490                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
21491                        } catch (RemoteException e) {
21492                        }
21493                    }
21494                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
21495                } else {
21496                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21497                            || app.systemNoUi) && app.pendingUiClean) {
21498                        // If this application is now in the background and it
21499                        // had done UI, then give it the special trim level to
21500                        // have it free UI resources.
21501                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
21502                        if (app.trimMemoryLevel < level && app.thread != null) {
21503                            try {
21504                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21505                                        "Trimming memory of bg-ui " + app.processName
21506                                        + " to " + level);
21507                                app.thread.scheduleTrimMemory(level);
21508                            } catch (RemoteException e) {
21509                            }
21510                        }
21511                        app.pendingUiClean = false;
21512                    }
21513                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
21514                        try {
21515                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21516                                    "Trimming memory of fg " + app.processName
21517                                    + " to " + fgTrimLevel);
21518                            app.thread.scheduleTrimMemory(fgTrimLevel);
21519                        } catch (RemoteException e) {
21520                        }
21521                    }
21522                    app.trimMemoryLevel = fgTrimLevel;
21523                }
21524            }
21525        } else {
21526            if (mLowRamStartTime != 0) {
21527                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
21528                mLowRamStartTime = 0;
21529            }
21530            for (int i=N-1; i>=0; i--) {
21531                ProcessRecord app = mLruProcesses.get(i);
21532                if (allChanged || app.procStateChanged) {
21533                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
21534                    app.procStateChanged = false;
21535                }
21536                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21537                        || app.systemNoUi) && app.pendingUiClean) {
21538                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
21539                            && app.thread != null) {
21540                        try {
21541                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21542                                    "Trimming memory of ui hidden " + app.processName
21543                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
21544                            app.thread.scheduleTrimMemory(
21545                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
21546                        } catch (RemoteException e) {
21547                        }
21548                    }
21549                    app.pendingUiClean = false;
21550                }
21551                app.trimMemoryLevel = 0;
21552            }
21553        }
21554
21555        if (mAlwaysFinishActivities) {
21556            // Need to do this on its own message because the stack may not
21557            // be in a consistent state at this point.
21558            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
21559        }
21560
21561        if (allChanged) {
21562            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
21563        }
21564
21565        // Update from any uid changes.
21566        if (mLocalPowerManager != null) {
21567            mLocalPowerManager.startUidChanges();
21568        }
21569        for (int i=mActiveUids.size()-1; i>=0; i--) {
21570            final UidRecord uidRec = mActiveUids.valueAt(i);
21571            int uidChange = UidRecord.CHANGE_PROCSTATE;
21572            if (uidRec.setProcState != uidRec.curProcState) {
21573                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21574                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
21575                        + " to " + uidRec.curProcState);
21576                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
21577                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
21578                        uidRec.lastBackgroundTime = nowElapsed;
21579                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
21580                            // Note: the background settle time is in elapsed realtime, while
21581                            // the handler time base is uptime.  All this means is that we may
21582                            // stop background uids later than we had intended, but that only
21583                            // happens because the device was sleeping so we are okay anyway.
21584                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
21585                        }
21586                    }
21587                } else {
21588                    if (uidRec.idle) {
21589                        uidChange = UidRecord.CHANGE_ACTIVE;
21590                        uidRec.idle = false;
21591                    }
21592                    uidRec.lastBackgroundTime = 0;
21593                }
21594                uidRec.setProcState = uidRec.curProcState;
21595                enqueueUidChangeLocked(uidRec, -1, uidChange);
21596                noteUidProcessState(uidRec.uid, uidRec.curProcState);
21597            }
21598        }
21599        if (mLocalPowerManager != null) {
21600            mLocalPowerManager.finishUidChanges();
21601        }
21602
21603        if (mProcessStats.shouldWriteNowLocked(now)) {
21604            mHandler.post(new Runnable() {
21605                @Override public void run() {
21606                    synchronized (ActivityManagerService.this) {
21607                        mProcessStats.writeStateAsyncLocked();
21608                    }
21609                }
21610            });
21611        }
21612
21613        if (DEBUG_OOM_ADJ) {
21614            final long duration = SystemClock.uptimeMillis() - now;
21615            if (false) {
21616                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
21617                        new RuntimeException("here").fillInStackTrace());
21618            } else {
21619                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
21620            }
21621        }
21622    }
21623
21624    @Override
21625    public void makePackageIdle(String packageName, int userId) {
21626        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
21627                != PackageManager.PERMISSION_GRANTED) {
21628            String msg = "Permission Denial: makePackageIdle() from pid="
21629                    + Binder.getCallingPid()
21630                    + ", uid=" + Binder.getCallingUid()
21631                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
21632            Slog.w(TAG, msg);
21633            throw new SecurityException(msg);
21634        }
21635        final int callingPid = Binder.getCallingPid();
21636        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
21637                userId, true, ALLOW_FULL_ONLY, "makePackageIdle", null);
21638        long callingId = Binder.clearCallingIdentity();
21639        synchronized(this) {
21640            try {
21641                IPackageManager pm = AppGlobals.getPackageManager();
21642                int pkgUid = -1;
21643                try {
21644                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES
21645                            | MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM);
21646                } catch (RemoteException e) {
21647                }
21648                if (pkgUid == -1) {
21649                    throw new IllegalArgumentException("Unknown package name " + packageName);
21650                }
21651
21652                if (mLocalPowerManager != null) {
21653                    mLocalPowerManager.startUidChanges();
21654                }
21655                final int appId = UserHandle.getAppId(pkgUid);
21656                final int N = mActiveUids.size();
21657                for (int i=N-1; i>=0; i--) {
21658                    final UidRecord uidRec = mActiveUids.valueAt(i);
21659                    final long bgTime = uidRec.lastBackgroundTime;
21660                    if (bgTime > 0 && !uidRec.idle) {
21661                        if (UserHandle.getAppId(uidRec.uid) == appId) {
21662                            if (userId == UserHandle.USER_ALL ||
21663                                    userId == UserHandle.getUserId(uidRec.uid)) {
21664                                uidRec.idle = true;
21665                                Slog.w(TAG, "Idling uid " + UserHandle.formatUid(uidRec.uid)
21666                                        + " from package " + packageName + " user " + userId);
21667                                doStopUidLocked(uidRec.uid, uidRec);
21668                            }
21669                        }
21670                    }
21671                }
21672            } finally {
21673                if (mLocalPowerManager != null) {
21674                    mLocalPowerManager.finishUidChanges();
21675                }
21676                Binder.restoreCallingIdentity(callingId);
21677            }
21678        }
21679    }
21680
21681    final void idleUids() {
21682        synchronized (this) {
21683            final int N = mActiveUids.size();
21684            if (N <= 0) {
21685                return;
21686            }
21687            final long nowElapsed = SystemClock.elapsedRealtime();
21688            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
21689            long nextTime = 0;
21690            if (mLocalPowerManager != null) {
21691                mLocalPowerManager.startUidChanges();
21692            }
21693            for (int i=N-1; i>=0; i--) {
21694                final UidRecord uidRec = mActiveUids.valueAt(i);
21695                final long bgTime = uidRec.lastBackgroundTime;
21696                if (bgTime > 0 && !uidRec.idle) {
21697                    if (bgTime <= maxBgTime) {
21698                        uidRec.idle = true;
21699                        doStopUidLocked(uidRec.uid, uidRec);
21700                    } else {
21701                        if (nextTime == 0 || nextTime > bgTime) {
21702                            nextTime = bgTime;
21703                        }
21704                    }
21705                }
21706            }
21707            if (mLocalPowerManager != null) {
21708                mLocalPowerManager.finishUidChanges();
21709            }
21710            if (nextTime > 0) {
21711                mHandler.removeMessages(IDLE_UIDS_MSG);
21712                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
21713                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
21714            }
21715        }
21716    }
21717
21718    final void runInBackgroundDisabled(int uid) {
21719        synchronized (this) {
21720            UidRecord uidRec = mActiveUids.get(uid);
21721            if (uidRec != null) {
21722                // This uid is actually running...  should it be considered background now?
21723                if (uidRec.idle) {
21724                    doStopUidLocked(uidRec.uid, uidRec);
21725                }
21726            } else {
21727                // This uid isn't actually running...  still send a report about it being "stopped".
21728                doStopUidLocked(uid, null);
21729            }
21730        }
21731    }
21732
21733    final void doStopUidLocked(int uid, final UidRecord uidRec) {
21734        mServices.stopInBackgroundLocked(uid);
21735        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
21736    }
21737
21738    final void trimApplications() {
21739        synchronized (this) {
21740            int i;
21741
21742            // First remove any unused application processes whose package
21743            // has been removed.
21744            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
21745                final ProcessRecord app = mRemovedProcesses.get(i);
21746                if (app.activities.size() == 0
21747                        && app.curReceivers.isEmpty() && app.services.size() == 0) {
21748                    Slog.i(
21749                        TAG, "Exiting empty application process "
21750                        + app.toShortString() + " ("
21751                        + (app.thread != null ? app.thread.asBinder() : null)
21752                        + ")\n");
21753                    if (app.pid > 0 && app.pid != MY_PID) {
21754                        app.kill("empty", false);
21755                    } else {
21756                        try {
21757                            app.thread.scheduleExit();
21758                        } catch (Exception e) {
21759                            // Ignore exceptions.
21760                        }
21761                    }
21762                    cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
21763                    mRemovedProcesses.remove(i);
21764
21765                    if (app.persistent) {
21766                        addAppLocked(app.info, false, null /* ABI override */);
21767                    }
21768                }
21769            }
21770
21771            // Now update the oom adj for all processes.
21772            updateOomAdjLocked();
21773        }
21774    }
21775
21776    /** This method sends the specified signal to each of the persistent apps */
21777    public void signalPersistentProcesses(int sig) throws RemoteException {
21778        if (sig != Process.SIGNAL_USR1) {
21779            throw new SecurityException("Only SIGNAL_USR1 is allowed");
21780        }
21781
21782        synchronized (this) {
21783            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
21784                    != PackageManager.PERMISSION_GRANTED) {
21785                throw new SecurityException("Requires permission "
21786                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
21787            }
21788
21789            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
21790                ProcessRecord r = mLruProcesses.get(i);
21791                if (r.thread != null && r.persistent) {
21792                    Process.sendSignal(r.pid, sig);
21793                }
21794            }
21795        }
21796    }
21797
21798    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
21799        if (proc == null || proc == mProfileProc) {
21800            proc = mProfileProc;
21801            profileType = mProfileType;
21802            clearProfilerLocked();
21803        }
21804        if (proc == null) {
21805            return;
21806        }
21807        try {
21808            proc.thread.profilerControl(false, null, profileType);
21809        } catch (RemoteException e) {
21810            throw new IllegalStateException("Process disappeared");
21811        }
21812    }
21813
21814    private void clearProfilerLocked() {
21815        if (mProfileFd != null) {
21816            try {
21817                mProfileFd.close();
21818            } catch (IOException e) {
21819            }
21820        }
21821        mProfileApp = null;
21822        mProfileProc = null;
21823        mProfileFile = null;
21824        mProfileType = 0;
21825        mAutoStopProfiler = false;
21826        mSamplingInterval = 0;
21827    }
21828
21829    public boolean profileControl(String process, int userId, boolean start,
21830            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
21831
21832        try {
21833            synchronized (this) {
21834                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21835                // its own permission.
21836                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21837                        != PackageManager.PERMISSION_GRANTED) {
21838                    throw new SecurityException("Requires permission "
21839                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21840                }
21841
21842                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
21843                    throw new IllegalArgumentException("null profile info or fd");
21844                }
21845
21846                ProcessRecord proc = null;
21847                if (process != null) {
21848                    proc = findProcessLocked(process, userId, "profileControl");
21849                }
21850
21851                if (start && (proc == null || proc.thread == null)) {
21852                    throw new IllegalArgumentException("Unknown process: " + process);
21853                }
21854
21855                if (start) {
21856                    stopProfilerLocked(null, 0);
21857                    setProfileApp(proc.info, proc.processName, profilerInfo);
21858                    mProfileProc = proc;
21859                    mProfileType = profileType;
21860                    ParcelFileDescriptor fd = profilerInfo.profileFd;
21861                    try {
21862                        fd = fd.dup();
21863                    } catch (IOException e) {
21864                        fd = null;
21865                    }
21866                    profilerInfo.profileFd = fd;
21867                    proc.thread.profilerControl(start, profilerInfo, profileType);
21868                    fd = null;
21869                    mProfileFd = null;
21870                } else {
21871                    stopProfilerLocked(proc, profileType);
21872                    if (profilerInfo != null && profilerInfo.profileFd != null) {
21873                        try {
21874                            profilerInfo.profileFd.close();
21875                        } catch (IOException e) {
21876                        }
21877                    }
21878                }
21879
21880                return true;
21881            }
21882        } catch (RemoteException e) {
21883            throw new IllegalStateException("Process disappeared");
21884        } finally {
21885            if (profilerInfo != null && profilerInfo.profileFd != null) {
21886                try {
21887                    profilerInfo.profileFd.close();
21888                } catch (IOException e) {
21889                }
21890            }
21891        }
21892    }
21893
21894    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
21895        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
21896                userId, true, ALLOW_FULL_ONLY, callName, null);
21897        ProcessRecord proc = null;
21898        try {
21899            int pid = Integer.parseInt(process);
21900            synchronized (mPidsSelfLocked) {
21901                proc = mPidsSelfLocked.get(pid);
21902            }
21903        } catch (NumberFormatException e) {
21904        }
21905
21906        if (proc == null) {
21907            ArrayMap<String, SparseArray<ProcessRecord>> all
21908                    = mProcessNames.getMap();
21909            SparseArray<ProcessRecord> procs = all.get(process);
21910            if (procs != null && procs.size() > 0) {
21911                proc = procs.valueAt(0);
21912                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
21913                    for (int i=1; i<procs.size(); i++) {
21914                        ProcessRecord thisProc = procs.valueAt(i);
21915                        if (thisProc.userId == userId) {
21916                            proc = thisProc;
21917                            break;
21918                        }
21919                    }
21920                }
21921            }
21922        }
21923
21924        return proc;
21925    }
21926
21927    public boolean dumpHeap(String process, int userId, boolean managed,
21928            String path, ParcelFileDescriptor fd) throws RemoteException {
21929
21930        try {
21931            synchronized (this) {
21932                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21933                // its own permission (same as profileControl).
21934                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21935                        != PackageManager.PERMISSION_GRANTED) {
21936                    throw new SecurityException("Requires permission "
21937                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21938                }
21939
21940                if (fd == null) {
21941                    throw new IllegalArgumentException("null fd");
21942                }
21943
21944                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
21945                if (proc == null || proc.thread == null) {
21946                    throw new IllegalArgumentException("Unknown process: " + process);
21947                }
21948
21949                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21950                if (!isDebuggable) {
21951                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21952                        throw new SecurityException("Process not debuggable: " + proc);
21953                    }
21954                }
21955
21956                proc.thread.dumpHeap(managed, path, fd);
21957                fd = null;
21958                return true;
21959            }
21960        } catch (RemoteException e) {
21961            throw new IllegalStateException("Process disappeared");
21962        } finally {
21963            if (fd != null) {
21964                try {
21965                    fd.close();
21966                } catch (IOException e) {
21967                }
21968            }
21969        }
21970    }
21971
21972    @Override
21973    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
21974            String reportPackage) {
21975        if (processName != null) {
21976            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
21977                    "setDumpHeapDebugLimit()");
21978        } else {
21979            synchronized (mPidsSelfLocked) {
21980                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
21981                if (proc == null) {
21982                    throw new SecurityException("No process found for calling pid "
21983                            + Binder.getCallingPid());
21984                }
21985                if (!Build.IS_DEBUGGABLE
21986                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21987                    throw new SecurityException("Not running a debuggable build");
21988                }
21989                processName = proc.processName;
21990                uid = proc.uid;
21991                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
21992                    throw new SecurityException("Package " + reportPackage + " is not running in "
21993                            + proc);
21994                }
21995            }
21996        }
21997        synchronized (this) {
21998            if (maxMemSize > 0) {
21999                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
22000            } else {
22001                if (uid != 0) {
22002                    mMemWatchProcesses.remove(processName, uid);
22003                } else {
22004                    mMemWatchProcesses.getMap().remove(processName);
22005                }
22006            }
22007        }
22008    }
22009
22010    @Override
22011    public void dumpHeapFinished(String path) {
22012        synchronized (this) {
22013            if (Binder.getCallingPid() != mMemWatchDumpPid) {
22014                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
22015                        + " does not match last pid " + mMemWatchDumpPid);
22016                return;
22017            }
22018            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
22019                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
22020                        + " does not match last path " + mMemWatchDumpFile);
22021                return;
22022            }
22023            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
22024            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
22025        }
22026    }
22027
22028    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
22029    public void monitor() {
22030        synchronized (this) { }
22031    }
22032
22033    void onCoreSettingsChange(Bundle settings) {
22034        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
22035            ProcessRecord processRecord = mLruProcesses.get(i);
22036            try {
22037                if (processRecord.thread != null) {
22038                    processRecord.thread.setCoreSettings(settings);
22039                }
22040            } catch (RemoteException re) {
22041                /* ignore */
22042            }
22043        }
22044    }
22045
22046    // Multi-user methods
22047
22048    /**
22049     * Start user, if its not already running, but don't bring it to foreground.
22050     */
22051    @Override
22052    public boolean startUserInBackground(final int userId) {
22053        return mUserController.startUser(userId, /* foreground */ false);
22054    }
22055
22056    @Override
22057    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
22058        return mUserController.unlockUser(userId, token, secret, listener);
22059    }
22060
22061    @Override
22062    public boolean switchUser(final int targetUserId) {
22063        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
22064        int currentUserId;
22065        UserInfo targetUserInfo;
22066        synchronized (this) {
22067            currentUserId = mUserController.getCurrentUserIdLocked();
22068            targetUserInfo = mUserController.getUserInfo(targetUserId);
22069            if (targetUserId == currentUserId) {
22070                Slog.i(TAG, "user #" + targetUserId + " is already the current user");
22071                return true;
22072            }
22073            if (targetUserInfo == null) {
22074                Slog.w(TAG, "No user info for user #" + targetUserId);
22075                return false;
22076            }
22077            if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
22078                Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
22079                        + " when device is in demo mode");
22080                return false;
22081            }
22082            if (!targetUserInfo.supportsSwitchTo()) {
22083                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
22084                return false;
22085            }
22086            if (targetUserInfo.isManagedProfile()) {
22087                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
22088                return false;
22089            }
22090            mUserController.setTargetUserIdLocked(targetUserId);
22091        }
22092        if (mUserController.mUserSwitchUiEnabled) {
22093            UserInfo currentUserInfo = mUserController.getUserInfo(currentUserId);
22094            Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
22095            mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
22096            mUiHandler.sendMessage(mHandler.obtainMessage(
22097                    START_USER_SWITCH_UI_MSG, userNames));
22098        } else {
22099            mHandler.removeMessages(START_USER_SWITCH_FG_MSG);
22100            mHandler.sendMessage(mHandler.obtainMessage(
22101                    START_USER_SWITCH_FG_MSG, targetUserId, 0));
22102        }
22103        return true;
22104    }
22105
22106    void scheduleStartProfilesLocked() {
22107        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
22108            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
22109                    DateUtils.SECOND_IN_MILLIS);
22110        }
22111    }
22112
22113    @Override
22114    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
22115        return mUserController.stopUser(userId, force, callback);
22116    }
22117
22118    @Override
22119    public UserInfo getCurrentUser() {
22120        return mUserController.getCurrentUser();
22121    }
22122
22123    String getStartedUserState(int userId) {
22124        synchronized (this) {
22125            final UserState userState = mUserController.getStartedUserStateLocked(userId);
22126            return UserState.stateToString(userState.state);
22127        }
22128    }
22129
22130    @Override
22131    public boolean isUserRunning(int userId, int flags) {
22132        if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
22133                && checkCallingPermission(INTERACT_ACROSS_USERS)
22134                    != PackageManager.PERMISSION_GRANTED) {
22135            String msg = "Permission Denial: isUserRunning() from pid="
22136                    + Binder.getCallingPid()
22137                    + ", uid=" + Binder.getCallingUid()
22138                    + " requires " + INTERACT_ACROSS_USERS;
22139            Slog.w(TAG, msg);
22140            throw new SecurityException(msg);
22141        }
22142        synchronized (this) {
22143            return mUserController.isUserRunningLocked(userId, flags);
22144        }
22145    }
22146
22147    @Override
22148    public int[] getRunningUserIds() {
22149        if (checkCallingPermission(INTERACT_ACROSS_USERS)
22150                != PackageManager.PERMISSION_GRANTED) {
22151            String msg = "Permission Denial: isUserRunning() from pid="
22152                    + Binder.getCallingPid()
22153                    + ", uid=" + Binder.getCallingUid()
22154                    + " requires " + INTERACT_ACROSS_USERS;
22155            Slog.w(TAG, msg);
22156            throw new SecurityException(msg);
22157        }
22158        synchronized (this) {
22159            return mUserController.getStartedUserArrayLocked();
22160        }
22161    }
22162
22163    @Override
22164    public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
22165        mUserController.registerUserSwitchObserver(observer, name);
22166    }
22167
22168    @Override
22169    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
22170        mUserController.unregisterUserSwitchObserver(observer);
22171    }
22172
22173    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
22174        if (info == null) return null;
22175        ApplicationInfo newInfo = new ApplicationInfo(info);
22176        newInfo.initForUser(userId);
22177        return newInfo;
22178    }
22179
22180    public boolean isUserStopped(int userId) {
22181        synchronized (this) {
22182            return mUserController.getStartedUserStateLocked(userId) == null;
22183        }
22184    }
22185
22186    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
22187        if (aInfo == null
22188                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
22189            return aInfo;
22190        }
22191
22192        ActivityInfo info = new ActivityInfo(aInfo);
22193        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
22194        return info;
22195    }
22196
22197    private boolean processSanityChecksLocked(ProcessRecord process) {
22198        if (process == null || process.thread == null) {
22199            return false;
22200        }
22201
22202        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
22203        if (!isDebuggable) {
22204            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
22205                return false;
22206            }
22207        }
22208
22209        return true;
22210    }
22211
22212    public boolean startBinderTracking() throws RemoteException {
22213        synchronized (this) {
22214            mBinderTransactionTrackingEnabled = true;
22215            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
22216            // permission (same as profileControl).
22217            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
22218                    != PackageManager.PERMISSION_GRANTED) {
22219                throw new SecurityException("Requires permission "
22220                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
22221            }
22222
22223            for (int i = 0; i < mLruProcesses.size(); i++) {
22224                ProcessRecord process = mLruProcesses.get(i);
22225                if (!processSanityChecksLocked(process)) {
22226                    continue;
22227                }
22228                try {
22229                    process.thread.startBinderTracking();
22230                } catch (RemoteException e) {
22231                    Log.v(TAG, "Process disappared");
22232                }
22233            }
22234            return true;
22235        }
22236    }
22237
22238    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
22239        try {
22240            synchronized (this) {
22241                mBinderTransactionTrackingEnabled = false;
22242                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
22243                // permission (same as profileControl).
22244                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
22245                        != PackageManager.PERMISSION_GRANTED) {
22246                    throw new SecurityException("Requires permission "
22247                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
22248                }
22249
22250                if (fd == null) {
22251                    throw new IllegalArgumentException("null fd");
22252                }
22253
22254                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
22255                pw.println("Binder transaction traces for all processes.\n");
22256                for (ProcessRecord process : mLruProcesses) {
22257                    if (!processSanityChecksLocked(process)) {
22258                        continue;
22259                    }
22260
22261                    pw.println("Traces for process: " + process.processName);
22262                    pw.flush();
22263                    try {
22264                        TransferPipe tp = new TransferPipe();
22265                        try {
22266                            process.thread.stopBinderTrackingAndDump(tp.getWriteFd());
22267                            tp.go(fd.getFileDescriptor());
22268                        } finally {
22269                            tp.kill();
22270                        }
22271                    } catch (IOException e) {
22272                        pw.println("Failure while dumping IPC traces from " + process +
22273                                ".  Exception: " + e);
22274                        pw.flush();
22275                    } catch (RemoteException e) {
22276                        pw.println("Got a RemoteException while dumping IPC traces from " +
22277                                process + ".  Exception: " + e);
22278                        pw.flush();
22279                    }
22280                }
22281                fd = null;
22282                return true;
22283            }
22284        } finally {
22285            if (fd != null) {
22286                try {
22287                    fd.close();
22288                } catch (IOException e) {
22289                }
22290            }
22291        }
22292    }
22293
22294    private final class LocalService extends ActivityManagerInternal {
22295        @Override
22296        public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
22297                int targetUserId) {
22298            synchronized (ActivityManagerService.this) {
22299                ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid,
22300                        targetPkg, intent, null, targetUserId);
22301            }
22302        }
22303
22304        @Override
22305        public String checkContentProviderAccess(String authority, int userId) {
22306            return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
22307        }
22308
22309        @Override
22310        public void onWakefulnessChanged(int wakefulness) {
22311            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
22312        }
22313
22314        @Override
22315        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
22316                String processName, String abiOverride, int uid, Runnable crashHandler) {
22317            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
22318                    processName, abiOverride, uid, crashHandler);
22319        }
22320
22321        @Override
22322        public SleepToken acquireSleepToken(String tag) {
22323            Preconditions.checkNotNull(tag);
22324
22325            synchronized (ActivityManagerService.this) {
22326                SleepTokenImpl token = new SleepTokenImpl(tag);
22327                mSleepTokens.add(token);
22328                updateSleepIfNeededLocked();
22329                return token;
22330            }
22331        }
22332
22333        @Override
22334        public ComponentName getHomeActivityForUser(int userId) {
22335            synchronized (ActivityManagerService.this) {
22336                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
22337                return homeActivity == null ? null : homeActivity.realActivity;
22338            }
22339        }
22340
22341        @Override
22342        public void onUserRemoved(int userId) {
22343            synchronized (ActivityManagerService.this) {
22344                ActivityManagerService.this.onUserStoppedLocked(userId);
22345            }
22346        }
22347
22348        @Override
22349        public void onLocalVoiceInteractionStarted(IBinder activity,
22350                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
22351            synchronized (ActivityManagerService.this) {
22352                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
22353                        voiceSession, voiceInteractor);
22354            }
22355        }
22356
22357        @Override
22358        public void notifyStartingWindowDrawn() {
22359            synchronized (ActivityManagerService.this) {
22360                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
22361            }
22362        }
22363
22364        @Override
22365        public void notifyAppTransitionStarting(int reason) {
22366            synchronized (ActivityManagerService.this) {
22367                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
22368            }
22369        }
22370
22371        @Override
22372        public void notifyAppTransitionFinished() {
22373            synchronized (ActivityManagerService.this) {
22374                mStackSupervisor.notifyAppTransitionDone();
22375            }
22376        }
22377
22378        @Override
22379        public void notifyAppTransitionCancelled() {
22380            synchronized (ActivityManagerService.this) {
22381                mStackSupervisor.notifyAppTransitionDone();
22382            }
22383        }
22384
22385        @Override
22386        public List<IBinder> getTopVisibleActivities() {
22387            synchronized (ActivityManagerService.this) {
22388                return mStackSupervisor.getTopVisibleActivities();
22389            }
22390        }
22391
22392        @Override
22393        public void notifyDockedStackMinimizedChanged(boolean minimized) {
22394            synchronized (ActivityManagerService.this) {
22395                mStackSupervisor.setDockedStackMinimized(minimized);
22396            }
22397        }
22398
22399        @Override
22400        public void killForegroundAppsForUser(int userHandle) {
22401            synchronized (ActivityManagerService.this) {
22402                final ArrayList<ProcessRecord> procs = new ArrayList<>();
22403                final int NP = mProcessNames.getMap().size();
22404                for (int ip = 0; ip < NP; ip++) {
22405                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
22406                    final int NA = apps.size();
22407                    for (int ia = 0; ia < NA; ia++) {
22408                        final ProcessRecord app = apps.valueAt(ia);
22409                        if (app.persistent) {
22410                            // We don't kill persistent processes.
22411                            continue;
22412                        }
22413                        if (app.removed) {
22414                            procs.add(app);
22415                        } else if (app.userId == userHandle && app.foregroundActivities) {
22416                            app.removed = true;
22417                            procs.add(app);
22418                        }
22419                    }
22420                }
22421
22422                final int N = procs.size();
22423                for (int i = 0; i < N; i++) {
22424                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
22425                }
22426            }
22427        }
22428
22429        @Override
22430        public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
22431            if (!(target instanceof PendingIntentRecord)) {
22432                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
22433                return;
22434            }
22435            ((PendingIntentRecord) target).setWhitelistDuration(duration);
22436        }
22437
22438        @Override
22439        public void updatePersistentConfigurationForUser(@NonNull Configuration values,
22440                int userId) {
22441            Preconditions.checkNotNull(values, "Configuration must not be null");
22442            Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
22443            synchronized (ActivityManagerService.this) {
22444                updateConfigurationLocked(values, null, false, true, userId,
22445                        false /* deferResume */);
22446            }
22447        }
22448
22449        @Override
22450        public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
22451                Bundle bOptions) {
22452            Preconditions.checkNotNull(intents, "intents");
22453            final String[] resolvedTypes = new String[intents.length];
22454            for (int i = 0; i < intents.length; i++) {
22455                resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
22456            }
22457
22458            // UID of the package on user userId.
22459            // "= 0" is needed because otherwise catch(RemoteException) would make it look like
22460            // packageUid may not be initialized.
22461            int packageUid = 0;
22462            try {
22463                packageUid = AppGlobals.getPackageManager().getPackageUid(
22464                        packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
22465            } catch (RemoteException e) {
22466                // Shouldn't happen.
22467            }
22468
22469            synchronized (ActivityManagerService.this) {
22470                return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
22471                        /*resultTo*/ null, bOptions, userId);
22472            }
22473        }
22474
22475        @Override
22476        public int getUidProcessState(int uid) {
22477            return getUidState(uid);
22478        }
22479
22480        @Override
22481        public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
22482            synchronized (ActivityManagerService.this) {
22483
22484                // We might change the visibilities here, so prepare an empty app transition which
22485                // might be overridden later if we actually change visibilities.
22486                mWindowManager.prepareAppTransition(TRANSIT_NONE, false /* alwaysKeepCurrent */);
22487                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
22488                mWindowManager.executeAppTransition();
22489            }
22490            if (callback != null) {
22491                callback.run();
22492            }
22493        }
22494
22495        @Override
22496        public boolean isSystemReady() {
22497            // no need to synchronize(this) just to read & return the value
22498            return mSystemReady;
22499        }
22500
22501        @Override
22502        public void notifyKeyguardTrustedChanged() {
22503            synchronized (ActivityManagerService.this) {
22504                if (mKeyguardController.isKeyguardShowing()) {
22505                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
22506                }
22507            }
22508        }
22509    }
22510
22511    private final class SleepTokenImpl extends SleepToken {
22512        private final String mTag;
22513        private final long mAcquireTime;
22514
22515        public SleepTokenImpl(String tag) {
22516            mTag = tag;
22517            mAcquireTime = SystemClock.uptimeMillis();
22518        }
22519
22520        @Override
22521        public void release() {
22522            synchronized (ActivityManagerService.this) {
22523                if (mSleepTokens.remove(this)) {
22524                    updateSleepIfNeededLocked();
22525                }
22526            }
22527        }
22528
22529        @Override
22530        public String toString() {
22531            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
22532        }
22533    }
22534
22535    /**
22536     * An implementation of IAppTask, that allows an app to manage its own tasks via
22537     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
22538     * only the process that calls getAppTasks() can call the AppTask methods.
22539     */
22540    class AppTaskImpl extends IAppTask.Stub {
22541        private int mTaskId;
22542        private int mCallingUid;
22543
22544        public AppTaskImpl(int taskId, int callingUid) {
22545            mTaskId = taskId;
22546            mCallingUid = callingUid;
22547        }
22548
22549        private void checkCaller() {
22550            if (mCallingUid != Binder.getCallingUid()) {
22551                throw new SecurityException("Caller " + mCallingUid
22552                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
22553            }
22554        }
22555
22556        @Override
22557        public void finishAndRemoveTask() {
22558            checkCaller();
22559
22560            synchronized (ActivityManagerService.this) {
22561                long origId = Binder.clearCallingIdentity();
22562                try {
22563                    // We remove the task from recents to preserve backwards
22564                    if (!mStackSupervisor.removeTaskByIdLocked(mTaskId, false,
22565                            REMOVE_FROM_RECENTS)) {
22566                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22567                    }
22568                } finally {
22569                    Binder.restoreCallingIdentity(origId);
22570                }
22571            }
22572        }
22573
22574        @Override
22575        public ActivityManager.RecentTaskInfo getTaskInfo() {
22576            checkCaller();
22577
22578            synchronized (ActivityManagerService.this) {
22579                long origId = Binder.clearCallingIdentity();
22580                try {
22581                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22582                    if (tr == null) {
22583                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22584                    }
22585                    return createRecentTaskInfoFromTaskRecord(tr);
22586                } finally {
22587                    Binder.restoreCallingIdentity(origId);
22588                }
22589            }
22590        }
22591
22592        @Override
22593        public void moveToFront() {
22594            checkCaller();
22595            // Will bring task to front if it already has a root activity.
22596            final long origId = Binder.clearCallingIdentity();
22597            try {
22598                synchronized (this) {
22599                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
22600                }
22601            } finally {
22602                Binder.restoreCallingIdentity(origId);
22603            }
22604        }
22605
22606        @Override
22607        public int startActivity(IBinder whoThread, String callingPackage,
22608                Intent intent, String resolvedType, Bundle bOptions) {
22609            checkCaller();
22610
22611            int callingUser = UserHandle.getCallingUserId();
22612            TaskRecord tr;
22613            IApplicationThread appThread;
22614            synchronized (ActivityManagerService.this) {
22615                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22616                if (tr == null) {
22617                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22618                }
22619                appThread = IApplicationThread.Stub.asInterface(whoThread);
22620                if (appThread == null) {
22621                    throw new IllegalArgumentException("Bad app thread " + appThread);
22622                }
22623            }
22624            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
22625                    resolvedType, null, null, null, null, 0, 0, null, null,
22626                    null, bOptions, false, callingUser, null, tr);
22627        }
22628
22629        @Override
22630        public void setExcludeFromRecents(boolean exclude) {
22631            checkCaller();
22632
22633            synchronized (ActivityManagerService.this) {
22634                long origId = Binder.clearCallingIdentity();
22635                try {
22636                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22637                    if (tr == null) {
22638                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22639                    }
22640                    Intent intent = tr.getBaseIntent();
22641                    if (exclude) {
22642                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
22643                    } else {
22644                        intent.setFlags(intent.getFlags()
22645                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
22646                    }
22647                } finally {
22648                    Binder.restoreCallingIdentity(origId);
22649                }
22650            }
22651        }
22652    }
22653
22654    /**
22655     * Kill processes for the user with id userId and that depend on the package named packageName
22656     */
22657    @Override
22658    public void killPackageDependents(String packageName, int userId) {
22659        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
22660        if (packageName == null) {
22661            throw new NullPointerException(
22662                    "Cannot kill the dependents of a package without its name.");
22663        }
22664
22665        long callingId = Binder.clearCallingIdentity();
22666        IPackageManager pm = AppGlobals.getPackageManager();
22667        int pkgUid = -1;
22668        try {
22669            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
22670        } catch (RemoteException e) {
22671        }
22672        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
22673            throw new IllegalArgumentException(
22674                    "Cannot kill dependents of non-existing package " + packageName);
22675        }
22676        try {
22677            synchronized(this) {
22678                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
22679                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
22680                        "dep: " + packageName);
22681            }
22682        } finally {
22683            Binder.restoreCallingIdentity(callingId);
22684        }
22685    }
22686
22687    @Override
22688    public boolean canBypassWorkChallenge(PendingIntent intent) throws RemoteException {
22689        final int userId = intent.getCreatorUserHandle().getIdentifier();
22690        if (!mUserController.isUserRunningLocked(userId, ActivityManager.FLAG_AND_LOCKED)) {
22691            return false;
22692        }
22693        IIntentSender target = intent.getTarget();
22694        if (!(target instanceof PendingIntentRecord)) {
22695            return false;
22696        }
22697        final PendingIntentRecord record = (PendingIntentRecord) target;
22698        final ResolveInfo rInfo = mStackSupervisor.resolveIntent(record.key.requestIntent,
22699                record.key.requestResolvedType, userId, PackageManager.MATCH_DIRECT_BOOT_AWARE);
22700        // For direct boot aware activities, they can be shown without triggering a work challenge
22701        // before the profile user is unlocked.
22702        return rInfo != null && rInfo.activityInfo != null;
22703    }
22704
22705    @Override
22706    public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback)
22707            throws RemoteException {
22708        final long callingId = Binder.clearCallingIdentity();
22709        try {
22710            mKeyguardController.dismissKeyguard(token, callback);
22711        } finally {
22712            Binder.restoreCallingIdentity(callingId);
22713        }
22714    }
22715
22716    @Override
22717    public int restartUserInBackground(final int userId) {
22718        return mUserController.restartUser(userId, /* foreground */ false);
22719    }
22720
22721    /**
22722     * Attach an agent to the specified process (proces name or PID)
22723     */
22724    public void attachAgent(String process, String path) {
22725        try {
22726            synchronized (this) {
22727                ProcessRecord proc = findProcessLocked(process, UserHandle.USER_SYSTEM, "attachAgent");
22728                if (proc == null || proc.thread == null) {
22729                    throw new IllegalArgumentException("Unknown process: " + process);
22730                }
22731
22732                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
22733                if (!isDebuggable) {
22734                    if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
22735                        throw new SecurityException("Process not debuggable: " + proc);
22736                    }
22737                }
22738
22739                proc.thread.attachAgent(path);
22740            }
22741        } catch (RemoteException e) {
22742            throw new IllegalStateException("Process disappeared");
22743        }
22744    }
22745}
22746